diff --git a/server/helpers/logger.ts b/server/helpers/logger.ts index b8ae28b3f..9553f70e8 100644 --- a/server/helpers/logger.ts +++ b/server/helpers/logger.ts @@ -54,9 +54,11 @@ const jsonLoggerFormat = winston.format.printf(info => { const timestampFormatter = winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }) -const labelFormatter = winston.format.label({ - label -}) +const labelFormatter = (suffix?: string) => { + return winston.format.label({ + label: suffix ? `${label} ${suffix}` : label + }) +} const fileLoggerOptions: FileTransportOptions = { filename: path.join(CONFIG.STORAGE.LOG_DIR, LOG_FILENAME), @@ -72,25 +74,29 @@ if (CONFIG.LOG.ROTATION.ENABLED) { fileLoggerOptions.maxFiles = CONFIG.LOG.ROTATION.MAX_FILES } -const logger = winston.createLogger({ - level: CONFIG.LOG.LEVEL, - format: winston.format.combine( - labelFormatter, - winston.format.splat() - ), - transports: [ - new winston.transports.File(fileLoggerOptions), - new winston.transports.Console({ - handleExceptions: true, - format: winston.format.combine( - timestampFormatter, - winston.format.colorize(), - consoleLoggerFormat - ) - }) - ], - exitOnError: true -}) +const logger = buildLogger() + +function buildLogger (labelSuffix?: string) { + return winston.createLogger({ + level: CONFIG.LOG.LEVEL, + format: winston.format.combine( + labelFormatter(labelSuffix), + winston.format.splat() + ), + transports: [ + new winston.transports.File(fileLoggerOptions), + new winston.transports.Console({ + handleExceptions: true, + format: winston.format.combine( + timestampFormatter, + winston.format.colorize(), + consoleLoggerFormat + ) + }) + ], + exitOnError: true + }) +} function bunyanLogFactory (level: string) { return function () { @@ -123,6 +129,7 @@ const bunyanLogger = { // --------------------------------------------------------------------------- export { + buildLogger, timestampFormatter, labelFormatter, consoleLoggerFormat, 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 @@ +import { PluginModel } from '@server/models/server/plugin' +import { PeerTubeHelpers } from '@server/typings/plugins' + +function buildPluginHelpers (npmName: string, plugin: PluginModel): PeerTubeHelpers { + const logger = buildLogger(npmName) + + return { + logger + } +} + +export { + buildPluginHelpers +} + +// --------------------------------------------------------------------------- + +function buildLogger (npmName: string) { + return buildLogger(npmName) +} 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 { PluginTranslationPaths as PackagePluginTranslations } from '../../../shared/models/plugins/plugin-package-json.model' import { createReadStream, createWriteStream } from 'fs' -import { PLUGIN_GLOBAL_CSS_PATH, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES } from '../../initializers/constants' +import { PLUGIN_GLOBAL_CSS_PATH } from '../../initializers/constants' import { PluginType } from '../../../shared/models/plugins/plugin.type' import { installNpmPlugin, installNpmPluginFromDisk, removeNpmPlugin } from './yarn' import { outputFile, readJSON } from 'fs-extra' -import { PluginSettingsManager } from '../../../shared/models/plugins/plugin-settings-manager.model' -import { PluginStorageManager } from '../../../shared/models/plugins/plugin-storage-manager.model' import { ServerHook, ServerHookName, serverHookObject } from '../../../shared/models/plugins/server-hook.model' import { getHookType, internalRunHook } from '../../../shared/core-utils/plugins/hooks' import { RegisterServerOptions } from '../../typings/plugins/register-server-option.model' @@ -22,10 +20,8 @@ import { PluginLibrary } from '../../typings/plugins' import { ClientHtml } from '../client-html' import { RegisterServerHookOptions } from '../../../shared/models/plugins/register-server-hook.model' import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model' -import { PluginVideoLanguageManager } from '../../../shared/models/plugins/plugin-video-language-manager.model' -import { PluginVideoCategoryManager } from '../../../shared/models/plugins/plugin-video-category-manager.model' -import { PluginVideoLicenceManager } from '../../../shared/models/plugins/plugin-video-licence-manager.model' import { PluginTranslation } from '../../../shared/models/plugins/plugin-translation.model' +import { buildRegisterHelpers, reinitVideoConstants } from './register-helpers' export interface RegisteredPlugin { npmName: string @@ -54,17 +50,6 @@ export interface HookInformationValue { priority: number } -type AlterableVideoConstant = 'language' | 'licence' | 'category' -type VideoConstant = { [key in number | string]: string } -type UpdatedVideoConstant = { - [name in AlterableVideoConstant]: { - [npmName: string]: { - added: { key: number | string, label: string }[] - deleted: { key: number | string, label: string }[] - } - } -} - type PluginLocalesTranslations = { [locale: string]: PluginTranslation } @@ -78,12 +63,6 @@ export class PluginManager implements ServerHook { private hooks: { [name: string]: HookInformationValue[] } = {} private translations: PluginLocalesTranslations = {} - private readonly updatedVideoConstants: UpdatedVideoConstant = { - language: {}, - licence: {}, - category: {} - } - private constructor () { } @@ -197,7 +176,7 @@ export class PluginManager implements ServerHook { this.hooks[key] = this.hooks[key].filter(h => h.npmName !== npmName) } - this.reinitVideoConstants(plugin.npmName) + reinitVideoConstants(plugin.npmName) logger.info('Regenerating registered plugin CSS to global file.') await this.regeneratePluginGlobalCSS() @@ -472,127 +451,12 @@ export class PluginManager implements ServerHook { this.settings[npmName].push(options) } - const settingsManager: PluginSettingsManager = { - getSetting: (name: string) => PluginModel.getSetting(plugin.name, plugin.type, name), + const registerHelpers = buildRegisterHelpers(npmName, plugin) - setSetting: (name: string, value: string) => PluginModel.setSetting(plugin.name, plugin.type, name, value) - } - - const storageManager: PluginStorageManager = { - getData: (key: string) => PluginModel.getData(plugin.name, plugin.type, key), - - storeData: (key: string, data: any) => PluginModel.storeData(plugin.name, plugin.type, key, data) - } - - const videoLanguageManager: PluginVideoLanguageManager = { - addLanguage: (key: string, label: string) => this.addConstant({ npmName, type: 'language', obj: VIDEO_LANGUAGES, key, label }), - - deleteLanguage: (key: string) => this.deleteConstant({ npmName, type: 'language', obj: VIDEO_LANGUAGES, key }) - } - - const videoCategoryManager: PluginVideoCategoryManager = { - addCategory: (key: number, label: string) => this.addConstant({ npmName, type: 'category', obj: VIDEO_CATEGORIES, key, label }), - - deleteCategory: (key: number) => this.deleteConstant({ npmName, type: 'category', obj: VIDEO_CATEGORIES, key }) - } - - const videoLicenceManager: PluginVideoLicenceManager = { - addLicence: (key: number, label: string) => this.addConstant({ npmName, type: 'licence', obj: VIDEO_LICENCES, key, label }), - - deleteLicence: (key: number) => this.deleteConstant({ npmName, type: 'licence', obj: VIDEO_LICENCES, key }) - } - - const peertubeHelpers = { - logger - } - - return { + return Object.assign(registerHelpers, { registerHook, - registerSetting, - settingsManager, - storageManager, - videoLanguageManager, - videoCategoryManager, - videoLicenceManager, - peertubeHelpers - } - } - - private addConstant (parameters: { - npmName: string - type: AlterableVideoConstant - obj: VideoConstant - key: T - label: string - }) { - const { npmName, type, obj, key, label } = parameters - - if (obj[key]) { - logger.warn('Cannot add %s %s by plugin %s: key already exists.', type, npmName, key) - return false - } - - if (!this.updatedVideoConstants[type][npmName]) { - this.updatedVideoConstants[type][npmName] = { - added: [], - deleted: [] - } - } - - this.updatedVideoConstants[type][npmName].added.push({ key, label }) - obj[key] = label - - return true - } - - private deleteConstant (parameters: { - npmName: string - type: AlterableVideoConstant - obj: VideoConstant - key: T - }) { - const { npmName, type, obj, key } = parameters - - if (!obj[key]) { - logger.warn('Cannot delete %s %s by plugin %s: key does not exist.', type, npmName, key) - return false - } - - if (!this.updatedVideoConstants[type][npmName]) { - this.updatedVideoConstants[type][npmName] = { - added: [], - deleted: [] - } - } - - this.updatedVideoConstants[type][npmName].deleted.push({ key, label: obj[key] }) - delete obj[key] - - return true - } - - private reinitVideoConstants (npmName: string) { - const hash = { - language: VIDEO_LANGUAGES, - licence: VIDEO_LICENCES, - category: VIDEO_CATEGORIES - } - const types: AlterableVideoConstant[] = [ 'language', 'licence', 'category' ] - - for (const type of types) { - const updatedConstants = this.updatedVideoConstants[type][npmName] - if (!updatedConstants) continue - - for (const added of updatedConstants.added) { - delete hash[type][added.key] - } - - for (const deleted of updatedConstants.deleted) { - hash[type][deleted.key] = deleted.label - } - - delete this.updatedVideoConstants[type][npmName] - } + registerSetting + }) } 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 @@ +import { PluginSettingsManager } from '@shared/models/plugins/plugin-settings-manager.model' +import { PluginModel } from '@server/models/server/plugin' +import { PluginStorageManager } from '@shared/models/plugins/plugin-storage-manager.model' +import { PluginVideoLanguageManager } from '@shared/models/plugins/plugin-video-language-manager.model' +import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES } from '@server/initializers/constants' +import { PluginVideoLicenceManager } from '@shared/models/plugins/plugin-video-licence-manager.model' +import { PluginVideoCategoryManager } from '@shared/models/plugins/plugin-video-category-manager.model' +import { RegisterServerOptions } from '@server/typings/plugins' +import { buildPluginHelpers } from './plugin-helpers' +import { logger } from '@server/helpers/logger' + +type AlterableVideoConstant = 'language' | 'licence' | 'category' +type VideoConstant = { [key in number | string]: string } +type UpdatedVideoConstant = { + [name in AlterableVideoConstant]: { + [npmName: string]: { + added: { key: number | string, label: string }[] + deleted: { key: number | string, label: string }[] + } + } +} + +const updatedVideoConstants: UpdatedVideoConstant = { + language: {}, + licence: {}, + category: {} +} + +function buildRegisterHelpers (npmName: string, plugin: PluginModel): Omit { + const settingsManager = buildSettingsManager(plugin) + const storageManager = buildStorageManager(plugin) + + const videoLanguageManager = buildVideoLanguageManager(npmName) + + const videoCategoryManager = buildVideoCategoryManager(npmName) + const videoLicenceManager = buildVideoLicenceManager(npmName) + + const peertubeHelpers = buildPluginHelpers(npmName, plugin) + + return { + settingsManager, + storageManager, + videoLanguageManager, + videoCategoryManager, + videoLicenceManager, + peertubeHelpers + } +} + +function reinitVideoConstants (npmName: string) { + const hash = { + language: VIDEO_LANGUAGES, + licence: VIDEO_LICENCES, + category: VIDEO_CATEGORIES + } + const types: AlterableVideoConstant[] = [ 'language', 'licence', 'category' ] + + for (const type of types) { + const updatedConstants = updatedVideoConstants[type][npmName] + if (!updatedConstants) continue + + for (const added of updatedConstants.added) { + delete hash[type][added.key] + } + + for (const deleted of updatedConstants.deleted) { + hash[type][deleted.key] = deleted.label + } + + delete updatedVideoConstants[type][npmName] + } +} + +export { + buildRegisterHelpers, + reinitVideoConstants +} + +// --------------------------------------------------------------------------- + +function buildSettingsManager (plugin: PluginModel): PluginSettingsManager { + return { + getSetting: (name: string) => PluginModel.getSetting(plugin.name, plugin.type, name), + + setSetting: (name: string, value: string) => PluginModel.setSetting(plugin.name, plugin.type, name, value) + } +} + +function buildStorageManager (plugin: PluginModel): PluginStorageManager { + return { + getData: (key: string) => PluginModel.getData(plugin.name, plugin.type, key), + + storeData: (key: string, data: any) => PluginModel.storeData(plugin.name, plugin.type, key, data) + } +} + +function buildVideoLanguageManager (npmName: string): PluginVideoLanguageManager { + return { + addLanguage: (key: string, label: string) => addConstant({ npmName, type: 'language', obj: VIDEO_LANGUAGES, key, label }), + + deleteLanguage: (key: string) => deleteConstant({ npmName, type: 'language', obj: VIDEO_LANGUAGES, key }) + } +} + +function buildVideoCategoryManager (npmName: string): PluginVideoCategoryManager { + return { + addCategory: (key: number, label: string) => { + return addConstant({ npmName, type: 'category', obj: VIDEO_CATEGORIES, key, label }) + }, + + deleteCategory: (key: number) => { + return deleteConstant({ npmName, type: 'category', obj: VIDEO_CATEGORIES, key }) + } + } +} + +function buildVideoLicenceManager (npmName: string): PluginVideoLicenceManager { + return { + addLicence: (key: number, label: string) => { + return addConstant({ npmName, type: 'licence', obj: VIDEO_LICENCES, key, label }) + }, + + deleteLicence: (key: number) => { + return deleteConstant({ npmName, type: 'licence', obj: VIDEO_LICENCES, key }) + } + } +} + +function addConstant (parameters: { + npmName: string + type: AlterableVideoConstant + obj: VideoConstant + key: T + label: string +}) { + const { npmName, type, obj, key, label } = parameters + + if (obj[key]) { + logger.warn('Cannot add %s %s by plugin %s: key already exists.', type, npmName, key) + return false + } + + if (!updatedVideoConstants[type][npmName]) { + updatedVideoConstants[type][npmName] = { + added: [], + deleted: [] + } + } + + updatedVideoConstants[type][npmName].added.push({ key, label }) + obj[key] = label + + return true +} + +function deleteConstant (parameters: { + npmName: string + type: AlterableVideoConstant + obj: VideoConstant + key: T +}) { + const { npmName, type, obj, key } = parameters + + if (!obj[key]) { + logger.warn('Cannot delete %s %s by plugin %s: key does not exist.', type, npmName, key) + return false + } + + if (!updatedVideoConstants[type][npmName]) { + updatedVideoConstants[type][npmName] = { + added: [], + deleted: [] + } + } + + updatedVideoConstants[type][npmName].deleted.push({ key, label: obj[key] }) + delete obj[key] + + return true +} diff --git a/server/typings/plugins/register-server-option.model.ts b/server/typings/plugins/register-server-option.model.ts index 54753cc01..76ac3cb9a 100644 --- a/server/typings/plugins/register-server-option.model.ts +++ b/server/typings/plugins/register-server-option.model.ts @@ -1,4 +1,3 @@ -import { logger } from '../../helpers/logger' import { PluginSettingsManager } from '../../../shared/models/plugins/plugin-settings-manager.model' import { PluginStorageManager } from '../../../shared/models/plugins/plugin-storage-manager.model' import { RegisterServerHookOptions } from '../../../shared/models/plugins/register-server-hook.model' @@ -6,6 +5,11 @@ import { RegisterServerSettingOptions } from '../../../shared/models/plugins/reg import { PluginVideoCategoryManager } from '../../../shared/models/plugins/plugin-video-category-manager.model' import { PluginVideoLanguageManager } from '../../../shared/models/plugins/plugin-video-language-manager.model' import { PluginVideoLicenceManager } from '../../../shared/models/plugins/plugin-video-licence-manager.model' +import { Logger } from 'winston' + +export type PeerTubeHelpers = { + logger: Logger +} export type RegisterServerOptions = { registerHook: (options: RegisterServerHookOptions) => void @@ -20,7 +24,5 @@ export type RegisterServerOptions = { videoLanguageManager: PluginVideoLanguageManager videoLicenceManager: PluginVideoLicenceManager - peertubeHelpers: { - logger: typeof logger - } + peertubeHelpers: PeerTubeHelpers }