mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-23 01:27:14 +02:00
Refactor extension settings
This commit is contained in:
parent
649e7a9a7e
commit
90b620de00
@ -1,9 +1,9 @@
|
||||
import {IConfigClass} from 'typeconfig/common';
|
||||
import {ConfigProperty, IConfigClass} from 'typeconfig/common';
|
||||
import {Config, PrivateConfigClass} from '../../../common/config/private/Config';
|
||||
import {ConfigClassBuilder} from 'typeconfig/node';
|
||||
import {IExtensionConfig} from './IExtension';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {ObjectManagers} from '../ObjectManagers';
|
||||
import {ServerExtensionsEntryConfig} from '../../../common/config/private/subconfigs/ServerExtensionsConfig';
|
||||
|
||||
/**
|
||||
* Wraps to original config and makes sure all extension related config is loaded
|
||||
@ -29,11 +29,29 @@ export class ExtensionConfigWrapper {
|
||||
export class ExtensionConfig<C> implements IExtensionConfig<C> {
|
||||
public template: new() => C;
|
||||
|
||||
constructor(private readonly extensionId: string) {
|
||||
constructor(private readonly extensionFolder: string) {
|
||||
}
|
||||
|
||||
private findConfig(config: PrivateConfigClass) {
|
||||
let c = (config.Extensions.extensions || []).find(e => e.path === this.extensionFolder);
|
||||
if (!c) {
|
||||
c = new ServerExtensionsEntryConfig(this.extensionFolder);
|
||||
config.Extensions.extensions.push(c);
|
||||
}
|
||||
|
||||
if (!config.Extensions.extensions2[this.extensionFolder]) {
|
||||
Object.defineProperty(config.Extensions.extensions2, this.extensionFolder,
|
||||
ConfigProperty({type: ServerExtensionsEntryConfig})(config.Extensions.extensions2, this.extensionFolder));
|
||||
// config.Extensions.extensions2[this.extensionFolder] = c as any;
|
||||
|
||||
config.Extensions.extensions2[this.extensionFolder] = c;
|
||||
|
||||
}
|
||||
return config.Extensions.extensions2[this.extensionFolder];
|
||||
}
|
||||
|
||||
public getConfig(): C {
|
||||
return Config.Extensions.configs[this.extensionId] as C;
|
||||
return this.findConfig(Config).configs as C;
|
||||
}
|
||||
|
||||
public setTemplate(template: new() => C): void {
|
||||
@ -45,8 +63,15 @@ export class ExtensionConfig<C> implements IExtensionConfig<C> {
|
||||
if (!this.template) {
|
||||
return;
|
||||
}
|
||||
const conf = ConfigClassBuilder.attachPrivateInterface(new this.template());
|
||||
conf.__loadJSONObject(Utils.clone(config.Extensions.configs[this.extensionId] || {}));
|
||||
config.Extensions.configs[this.extensionId] = conf;
|
||||
|
||||
const confTemplate = ConfigClassBuilder.attachPrivateInterface(new this.template());
|
||||
const extConf = this.findConfig(config);
|
||||
// confTemplate.__loadJSONObject(Utils.clone(extConf.configs || {}));
|
||||
//extConf.configs = confTemplate;
|
||||
Object.defineProperty(config.Extensions.extensions2[this.extensionFolder].configs, this.extensionFolder,
|
||||
ConfigProperty({type: this.template})(config.Extensions.extensions2[this.extensionFolder], this.extensionFolder));
|
||||
console.log(config.Extensions.extensions2[this.extensionFolder].configs);
|
||||
config.Extensions.extensions2[this.extensionFolder].configs = confTemplate as any;
|
||||
console.log(config.Extensions.extensions2[this.extensionFolder].configs);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import {SQLConnection} from '../database/SQLConnection';
|
||||
import {ExtensionObject} from './ExtensionObject';
|
||||
import {ExtensionDecoratorObject} from './ExtensionDecorator';
|
||||
import * as util from 'util';
|
||||
import {ServerExtensionsEntryConfig} from '../../../common/config/private/subconfigs/ServerExtensionsConfig';
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const exec = util.promisify(require('child_process').exec);
|
||||
|
||||
@ -70,13 +71,23 @@ export class ExtensionManager implements IObjectManager {
|
||||
return;
|
||||
}
|
||||
|
||||
Config.Extensions.list = fs
|
||||
.readdirSync(ProjectPath.ExtensionFolder)
|
||||
.filter((f): boolean =>
|
||||
fs.statSync(path.join(ProjectPath.ExtensionFolder, f)).isDirectory()
|
||||
);
|
||||
Config.Extensions.list.sort();
|
||||
Logger.debug(LOG_TAG, 'Extensions found ', JSON.stringify(Config.Extensions.list));
|
||||
|
||||
const extList = fs
|
||||
.readdirSync(ProjectPath.ExtensionFolder)
|
||||
.filter((f): boolean =>
|
||||
fs.statSync(path.join(ProjectPath.ExtensionFolder, f)).isDirectory()
|
||||
);
|
||||
extList.sort();
|
||||
|
||||
// delete not existing extensions
|
||||
Config.Extensions.extensions = Config.Extensions.extensions.filter(ec => extList.indexOf(ec.path) !== -1);
|
||||
|
||||
// Add new extensions
|
||||
const ePaths = Config.Extensions.extensions.map(ec => ec.path);
|
||||
extList.filter(ep => ePaths.indexOf(ep) === -1).forEach(ep =>
|
||||
Config.Extensions.extensions.push(new ServerExtensionsEntryConfig(ep)));
|
||||
|
||||
Logger.debug(LOG_TAG, 'Extensions found ', JSON.stringify(Config.Extensions.extensions.map(ec => ec.path)));
|
||||
}
|
||||
|
||||
private createUniqueExtensionObject(name: string, folder: string): IExtensionObject<unknown> {
|
||||
@ -95,8 +106,8 @@ export class ExtensionManager implements IObjectManager {
|
||||
|
||||
private async initExtensions() {
|
||||
|
||||
for (let i = 0; i < Config.Extensions.list.length; ++i) {
|
||||
const extFolder = Config.Extensions.list[i];
|
||||
for (let i = 0; i < Config.Extensions.extensions.length; ++i) {
|
||||
const extFolder = Config.Extensions.extensions[i].path;
|
||||
let extName = extFolder;
|
||||
const extPath = path.join(ProjectPath.ExtensionFolder, extFolder);
|
||||
const serverExtPath = path.join(extPath, 'server.js');
|
||||
@ -122,7 +133,7 @@ export class ExtensionManager implements IObjectManager {
|
||||
const ext = require(serverExtPath);
|
||||
if (typeof ext?.init === 'function') {
|
||||
Logger.debug(LOG_TAG, 'Running init on extension: ' + extFolder);
|
||||
await ext?.init(this.createUniqueExtensionObject(extName, extPath));
|
||||
await ext?.init(this.createUniqueExtensionObject(extName, extFolder));
|
||||
}
|
||||
}
|
||||
if (Config.Extensions.cleanUpUnusedTables) {
|
||||
|
@ -26,7 +26,7 @@ export class ExtensionObject<C> implements IExtensionObject<C> {
|
||||
events: IExtensionEvents) {
|
||||
const logger = createLoggerWrapper(`[Extension][${extensionId}]`);
|
||||
this._app = new ExtensionApp();
|
||||
this.config = new ExtensionConfig<C>(extensionId);
|
||||
this.config = new ExtensionConfig<C>(folder);
|
||||
this.db = new ExtensionDB(logger);
|
||||
this.paths = ProjectPath;
|
||||
this.Logger = logger;
|
||||
|
@ -11,7 +11,6 @@ import {
|
||||
} from '../../entities/job/JobScheduleDTO';
|
||||
import {
|
||||
ClientConfig,
|
||||
ClientExtensionsConfig,
|
||||
ClientGPXCompressingConfig,
|
||||
ClientMediaConfig,
|
||||
ClientMetaFileConfig,
|
||||
@ -30,7 +29,8 @@ import {SearchQueryDTO, SearchQueryTypes, TextSearch,} from '../../entities/Sear
|
||||
import {SortByTypes} from '../../entities/SortingMethods';
|
||||
import {UserRoles} from '../../entities/UserDTO';
|
||||
import {MediaPickDTO} from '../../entities/MediaPickDTO';
|
||||
import {MessagingConfig} from './MessagingConfig';
|
||||
import {ServerExtensionsConfig} from './subconfigs/ServerExtensionsConfig';
|
||||
import {MessagingConfig} from './subconfigs/MessagingConfig';
|
||||
|
||||
declare let $localize: (s: TemplateStringsArray) => string;
|
||||
|
||||
@ -966,35 +966,6 @@ export class ServerServiceConfig extends ClientServiceConfig {
|
||||
}
|
||||
|
||||
|
||||
@SubConfigClass<TAGS>({softReadonly: true})
|
||||
export class ServerExtensionsConfig extends ClientExtensionsConfig {
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Extension folder`,
|
||||
priority: ConfigPriority.underTheHood,
|
||||
dockerSensitive: true
|
||||
},
|
||||
description: $localize`Folder where the app stores the extensions. Extensions live in their sub-folders.`,
|
||||
})
|
||||
folder: string = 'extensions';
|
||||
|
||||
@ConfigProperty({volatile: true})
|
||||
list: string[] = [];
|
||||
|
||||
@ConfigProperty({type: 'object'})
|
||||
configs: Record<string, unknown> = {};
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Clean up unused tables`,
|
||||
priority: ConfigPriority.underTheHood,
|
||||
},
|
||||
description: $localize`Automatically removes all tables from the DB that are not used anymore.`,
|
||||
})
|
||||
cleanUpUnusedTables: boolean = true;
|
||||
}
|
||||
|
||||
@SubConfigClass({softReadonly: true})
|
||||
export class ServerEnvironmentConfig {
|
||||
@ConfigProperty({volatile: true})
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-inferrable-types */
|
||||
import {ConfigProperty, SubConfigClass} from 'typeconfig/common';
|
||||
import {ConfigPriority, TAGS} from '../public/ClientConfig';
|
||||
import {ConfigPriority, TAGS} from '../../public/ClientConfig';
|
||||
|
||||
declare let $localize: (s: TemplateStringsArray) => string;
|
||||
|
@ -0,0 +1,78 @@
|
||||
/* eslint-disable @typescript-eslint/no-inferrable-types */
|
||||
import {ConfigProperty, SubConfigClass} from 'typeconfig/common';
|
||||
import {ClientExtensionsConfig, ConfigPriority, TAGS} from '../../public/ClientConfig';
|
||||
import {IConfigClassPrivate} from '../../../../../node_modules/typeconfig/src/decorators/class/IConfigClass';
|
||||
|
||||
@SubConfigClass<TAGS>({softReadonly: true})
|
||||
export class ServerExtensionsEntryConfig {
|
||||
|
||||
constructor(path: string = '') {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Enabled`,
|
||||
priority: ConfigPriority.advanced,
|
||||
},
|
||||
})
|
||||
enabled: boolean = true;
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Extension folder`,
|
||||
priority: ConfigPriority.underTheHood,
|
||||
},
|
||||
description: $localize`Folder where the app stores all extensions. Individual extensions live in their own sub-folders.`,
|
||||
})
|
||||
path: string = '';
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Config`,
|
||||
priority: ConfigPriority.advanced
|
||||
}
|
||||
})
|
||||
configs: IConfigClassPrivate<unknown>;
|
||||
}
|
||||
|
||||
@SubConfigClass<TAGS>({softReadonly: true})
|
||||
export class ServerExtensionsConfig extends ClientExtensionsConfig {
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Extension folder`,
|
||||
priority: ConfigPriority.underTheHood,
|
||||
dockerSensitive: true
|
||||
},
|
||||
description: $localize`Folder where the app stores all extensions. Individual extensions live in their own sub-folders.`,
|
||||
})
|
||||
folder: string = 'extensions';
|
||||
|
||||
|
||||
@ConfigProperty({
|
||||
arrayType: ServerExtensionsEntryConfig,
|
||||
tags: {
|
||||
name: $localize`Installed extensions`,
|
||||
priority: ConfigPriority.advanced
|
||||
}
|
||||
})
|
||||
extensions: ServerExtensionsEntryConfig[] = [];
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Installed extensions2`,
|
||||
priority: ConfigPriority.advanced
|
||||
}
|
||||
})
|
||||
extensions2: Record<string, ServerExtensionsEntryConfig> = {};
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Clean up unused tables`,
|
||||
priority: ConfigPriority.underTheHood,
|
||||
},
|
||||
description: $localize`Automatically removes all tables from the DB that are not used anymore.`,
|
||||
})
|
||||
cleanUpUnusedTables: boolean = true;
|
||||
}
|
@ -19,6 +19,7 @@ import {enumToTranslatedArray} from '../../../EnumTranslations';
|
||||
import {BsModalService} from 'ngx-bootstrap/modal';
|
||||
import {CustomSettingsEntries} from '../CustomSettingsEntries';
|
||||
import {GroupByTypes, SortByTypes} from '../../../../../../common/entities/SortingMethods';
|
||||
import { ServerExtensionsEntryConfig } from '../../../../../../common/config/private/subconfigs/ServerExtensionsConfig';
|
||||
|
||||
interface IState {
|
||||
shouldHide(): boolean;
|
||||
@ -232,6 +233,8 @@ export class SettingsEntryComponent
|
||||
this.arrayType = 'MapPathGroupThemeConfig';
|
||||
} else if (this.state.arrayType === UserConfig) {
|
||||
this.arrayType = 'UserConfig';
|
||||
} else if (this.state.arrayType === ServerExtensionsEntryConfig) {
|
||||
this.arrayType = 'ServerExtensionsEntryConfig';
|
||||
} else if (this.state.arrayType === JobScheduleConfig) {
|
||||
this.arrayType = 'JobScheduleConfig';
|
||||
} else {
|
||||
@ -253,6 +256,7 @@ export class SettingsEntryComponent
|
||||
this.arrayType !== 'MapLayers' &&
|
||||
this.arrayType !== 'NavigationLinkConfig' &&
|
||||
this.arrayType !== 'MapPathGroupConfig' &&
|
||||
this.arrayType !== 'ServerExtensionsEntryConfig' &&
|
||||
this.arrayType !== 'MapPathGroupThemeConfig' &&
|
||||
this.arrayType !== 'JobScheduleConfig' &&
|
||||
this.arrayType !== 'UserConfig') {
|
||||
|
Loading…
Reference in New Issue
Block a user