From 4208fe7f1f7e34946777853838c28eed678bdabc Mon Sep 17 00:00:00 2001 From: "Patrik J. Braun" Date: Tue, 10 Dec 2019 16:17:35 +0100 Subject: [PATCH] refactoring config file fixing task setting issue --- src/backend/middlewares/RenderingMWs.ts | 4 +- src/backend/middlewares/admin/SettingsMWs.ts | 4 +- src/common/config/private/Config.ts | 4 +- src/common/config/private/ConfigClass.ts | 72 +++++++++ .../config/private/PrivateConfigClass.ts | 144 ------------------ .../private/PrivateConfigDefaultsClass.ts | 83 ++++++++++ .../app/ui/settings/settings.service.ts | 120 +-------------- .../tasks/tasks.settings.component.html | 16 +- .../tasks/tasks.settings.component.ts | 22 +-- 9 files changed, 185 insertions(+), 284 deletions(-) create mode 100644 src/common/config/private/ConfigClass.ts delete mode 100644 src/common/config/private/PrivateConfigClass.ts create mode 100644 src/common/config/private/PrivateConfigDefaultsClass.ts diff --git a/src/backend/middlewares/RenderingMWs.ts b/src/backend/middlewares/RenderingMWs.ts index a4e804d9..fe835fbb 100644 --- a/src/backend/middlewares/RenderingMWs.ts +++ b/src/backend/middlewares/RenderingMWs.ts @@ -4,7 +4,7 @@ import {Utils} from '../../common/Utils'; import {Message} from '../../common/entities/Message'; import {SharingDTO} from '../../common/entities/SharingDTO'; import {Config} from '../../common/config/private/Config'; -import {PrivateConfigClass} from '../../common/config/private/PrivateConfigClass'; +import {ConfigClass} from '../../common/config/private/PrivateConfigClass'; import {UserRoles} from '../../common/entities/UserDTO'; import {NotificationManager} from '../model/NotifocationManager'; import {Logger} from '../Logger'; @@ -55,7 +55,7 @@ export class RenderingMWs { public static renderConfig(req: Request, res: Response, next: NextFunction) { - const message = new Message(null, Config.original()); + const message = new Message(null, Config.original()); res.json(message); } diff --git a/src/backend/middlewares/admin/SettingsMWs.ts b/src/backend/middlewares/admin/SettingsMWs.ts index a970db38..67919d0f 100644 --- a/src/backend/middlewares/admin/SettingsMWs.ts +++ b/src/backend/middlewares/admin/SettingsMWs.ts @@ -10,7 +10,7 @@ import {ClientConfig} from '../../../common/config/public/ConfigClass'; import {BasicConfigDTO} from '../../../common/entities/settings/BasicConfigDTO'; import {OtherConfigDTO} from '../../../common/entities/settings/OtherConfigDTO'; import {ProjectPath} from '../../ProjectPath'; -import {PrivateConfigClass} from '../../../common/config/private/PrivateConfigClass'; +import {ConfigClass} from '../../../common/config/private/PrivateConfigClass'; import {ServerConfig} from '../../../common/config/private/IPrivateConfig'; const LOG_TAG = '[SettingsMWs]'; @@ -352,7 +352,7 @@ export class SettingsMWs { Config.Client.Other.NavBar.showItemCount = settings.Client.NavBar.showItemCount; // only updating explicitly set config (not saving config set by the diagnostics) - const original: PrivateConfigClass = Config.original(); + const original: ConfigClass = Config.original(); original.Client.Other.enableCache = settings.Client.enableCache; original.Client.Other.captionFirstNaming = settings.Client.captionFirstNaming; original.Client.Other.enableOnScrollRendering = settings.Client.enableOnScrollRendering; diff --git a/src/common/config/private/Config.ts b/src/common/config/private/Config.ts index fa6d19c4..0b1e6e22 100644 --- a/src/common/config/private/Config.ts +++ b/src/common/config/private/Config.ts @@ -1,5 +1,5 @@ -import {PrivateConfigClass} from './PrivateConfigClass'; +import {ConfigClass} from './ConfigClass'; -export let Config = new PrivateConfigClass(); +export let Config = new ConfigClass(); Config.load(); diff --git a/src/common/config/private/ConfigClass.ts b/src/common/config/private/ConfigClass.ts new file mode 100644 index 00000000..e9fe6900 --- /dev/null +++ b/src/common/config/private/ConfigClass.ts @@ -0,0 +1,72 @@ +import {IPrivateConfig, ServerConfig} from './IPrivateConfig'; +import * as path from 'path'; +import {ConfigLoader} from 'typeconfig'; +import {Utils} from '../../Utils'; +import {UserRoles} from '../../entities/UserDTO'; +import {PrivateConfigDefaultsClass} from './PrivateConfigDefaultsClass'; + +/** + * This configuration will be only at backend + */ +export class ConfigClass extends PrivateConfigDefaultsClass implements IPrivateConfig { + + private static readonly CONFIG_PATH = path.join(__dirname, './../../../../config.json'); + + private ConfigLoader: any; + + public setDatabaseType(type: ServerConfig.DatabaseType) { + this.Server.Database.type = type; + if (type === ServerConfig.DatabaseType.memory) { + this.Client.Search.enabled = false; + this.Client.Sharing.enabled = false; + } + } + + public load() { + this.addComment(); + ConfigLoader.loadBackendConfig(this, ConfigClass.CONFIG_PATH, + [['PORT', 'Server-port'], + ['MYSQL_HOST', 'Server-Database-mysql-host'], + ['MYSQL_PASSWORD', 'Server-Database-mysql-password'], + ['MYSQL_USERNAME', 'Server-Database-mysql-username'], + ['MYSQL_DATABASE', 'Server-Database-mysql-database']]); + this.removeComment(); + + if (Utils.enumToArray(UserRoles).map(r => r.key).indexOf(this.Client.unAuthenticatedUserRole) === -1) { + throw new Error('Unknown user role for Client.unAuthenticatedUserRole, found: ' + this.Client.unAuthenticatedUserRole); + } + if (Utils.enumToArray(ServerConfig.LogLevel).map(r => r.key).indexOf(this.Server.Log.level) === -1) { + throw new Error('Unknown Server.log.level, found: ' + this.Server.Log.level); + } + if (Utils.enumToArray(ServerConfig.SQLLogLevel).map(r => r.key).indexOf(this.Server.Log.sqlLevel) === -1) { + throw new Error('Unknown Server.log.level, found: ' + this.Server.Log.sqlLevel); + } + + } + + public save() { + try { + this.addComment(); + ConfigLoader.saveConfigFile(ConfigClass.CONFIG_PATH, this); + this.removeComment(); + } catch (e) { + throw new Error('Error during saving config: ' + e.toString()); + } + } + + public original(): ConfigClass { + const cfg = new ConfigClass(); + cfg.load(); + return cfg; + } + + private addComment() { + (this)['__NOTE'] = 'NOTE: this config is not intended for manual edit, ' + + 'use the app UI instead as it has comments and descriptions.'; + } + + private removeComment() { + delete (this)['__NOTE']; + } +} + diff --git a/src/common/config/private/PrivateConfigClass.ts b/src/common/config/private/PrivateConfigClass.ts deleted file mode 100644 index 3b78b8f0..00000000 --- a/src/common/config/private/PrivateConfigClass.ts +++ /dev/null @@ -1,144 +0,0 @@ -import {PublicConfigClass} from '../public/ConfigClass'; -import {IPrivateConfig, ServerConfig} from './IPrivateConfig'; -import * as path from 'path'; -import {ConfigLoader} from 'typeconfig'; -import {Utils} from '../../Utils'; -import {UserRoles} from '../../entities/UserDTO'; -import {TaskTriggerType} from '../../entities/task/TaskScheduleDTO'; -import {DefaultsTasks} from '../../entities/task/TaskDTO'; - -/** - * This configuration will be only at backend - */ -export class PrivateConfigClass extends PublicConfigClass implements IPrivateConfig { - - private static readonly CONFIG_PATH = path.join(__dirname, './../../../../config.json'); - public Server: ServerConfig.Config = { - port: 80, - host: '0.0.0.0', - imagesFolder: 'demo/images', - Thumbnail: { - folder: 'demo/TEMP', - processingLibrary: ServerConfig.ThumbnailProcessingLib.sharp, - qualityPriority: true, - personFaceMargin: 0.6 - }, - Log: { - level: ServerConfig.LogLevel.info, - sqlLevel: ServerConfig.SQLLogLevel.error - }, - sessionTimeout: 1000 * 60 * 60 * 24 * 7, - photoMetadataSize: 512 * 1024, - Database: { - type: ServerConfig.DatabaseType.sqlite, - mysql: { - host: '', - username: '', - password: '', - database: '' - - }, - sqlite: { - storage: 'sqlite.db' - } - }, - Sharing: { - updateTimeout: 1000 * 60 * 5 - }, - Threading: { - enable: true, - thumbnailThreads: 0 - }, - Indexing: { - folderPreviewSize: 2, - cachedFolderTimeout: 1000 * 60 * 60, - reIndexingSensitivity: ServerConfig.ReIndexingSensitivity.low, - excludeFolderList: [], - excludeFileList: [] - }, - Duplicates: { - listingLimit: 1000 - }, - Tasks: { - scheduled: [{ - taskName: DefaultsTasks[DefaultsTasks['Database Reset']], - config: {}, - trigger: {type: TaskTriggerType.never} - }, { - taskName: DefaultsTasks[DefaultsTasks.Indexing], - config: {}, - trigger: {type: TaskTriggerType.never} - }, { - taskName: DefaultsTasks[DefaultsTasks['Video Converting']], - config: {}, - trigger: {type: TaskTriggerType.never} - }] - }, - Video: { - transcoding: { - bitRate: 5 * 1024 * 1024, - codec: 'libx264', - format: 'mp4', - fps: 25, - resolution: 720 - } - } - }; - private ConfigLoader: any; - - public setDatabaseType(type: ServerConfig.DatabaseType) { - this.Server.Database.type = type; - if (type === ServerConfig.DatabaseType.memory) { - this.Client.Search.enabled = false; - this.Client.Sharing.enabled = false; - } - } - - public load() { - this.addComment(); - ConfigLoader.loadBackendConfig(this, PrivateConfigClass.CONFIG_PATH, - [['PORT', 'Server-port'], - ['MYSQL_HOST', 'Server-Database-mysql-host'], - ['MYSQL_PASSWORD', 'Server-Database-mysql-password'], - ['MYSQL_USERNAME', 'Server-Database-mysql-username'], - ['MYSQL_DATABASE', 'Server-Database-mysql-database']]); - this.removeComment(); - - if (Utils.enumToArray(UserRoles).map(r => r.key).indexOf(this.Client.unAuthenticatedUserRole) === -1) { - throw new Error('Unknown user role for Client.unAuthenticatedUserRole, found: ' + this.Client.unAuthenticatedUserRole); - } - if (Utils.enumToArray(ServerConfig.LogLevel).map(r => r.key).indexOf(this.Server.Log.level) === -1) { - throw new Error('Unknown Server.log.level, found: ' + this.Server.Log.level); - } - if (Utils.enumToArray(ServerConfig.SQLLogLevel).map(r => r.key).indexOf(this.Server.Log.sqlLevel) === -1) { - throw new Error('Unknown Server.log.level, found: ' + this.Server.Log.sqlLevel); - } - - } - - public save() { - try { - this.addComment(); - ConfigLoader.saveConfigFile(PrivateConfigClass.CONFIG_PATH, this); - this.removeComment(); - } catch (e) { - throw new Error('Error during saving config: ' + e.toString()); - } - } - - public original(): PrivateConfigClass { - const cfg = new PrivateConfigClass(); - cfg.load(); - return cfg; - } - - private addComment() { - (this)['__NOTE'] = 'NOTE: this config is not intended for manual edit, ' + - 'use the app UI instead as it has comments and descriptions.'; - } - - private removeComment() { - delete (this)['__NOTE']; - } -} - diff --git a/src/common/config/private/PrivateConfigDefaultsClass.ts b/src/common/config/private/PrivateConfigDefaultsClass.ts new file mode 100644 index 00000000..798bdae8 --- /dev/null +++ b/src/common/config/private/PrivateConfigDefaultsClass.ts @@ -0,0 +1,83 @@ +import {PublicConfigClass} from '../public/ConfigClass'; +import {IPrivateConfig, ServerConfig} from './IPrivateConfig'; +import {TaskTriggerType} from '../../entities/task/TaskScheduleDTO'; +import {DefaultsTasks} from '../../entities/task/TaskDTO'; + +/** + * This configuration will be only at backend + */ +export class PrivateConfigDefaultsClass extends PublicConfigClass implements IPrivateConfig { + + public Server: ServerConfig.Config = { + port: 80, + host: '0.0.0.0', + imagesFolder: 'demo/images', + Thumbnail: { + folder: 'demo/TEMP', + processingLibrary: ServerConfig.ThumbnailProcessingLib.sharp, + qualityPriority: true, + personFaceMargin: 0.6 + }, + Log: { + level: ServerConfig.LogLevel.info, + sqlLevel: ServerConfig.SQLLogLevel.error + }, + sessionTimeout: 1000 * 60 * 60 * 24 * 7, + photoMetadataSize: 512 * 1024, + Database: { + type: ServerConfig.DatabaseType.sqlite, + mysql: { + host: '', + username: '', + password: '', + database: '' + + }, + sqlite: { + storage: 'sqlite.db' + } + }, + Sharing: { + updateTimeout: 1000 * 60 * 5 + }, + Threading: { + enable: true, + thumbnailThreads: 0 + }, + Indexing: { + folderPreviewSize: 2, + cachedFolderTimeout: 1000 * 60 * 60, + reIndexingSensitivity: ServerConfig.ReIndexingSensitivity.low, + excludeFolderList: [], + excludeFileList: [] + }, + Duplicates: { + listingLimit: 1000 + }, + Tasks: { + scheduled: [{ + taskName: DefaultsTasks[DefaultsTasks['Database Reset']], + config: {}, + trigger: {type: TaskTriggerType.never} + }, { + taskName: DefaultsTasks[DefaultsTasks.Indexing], + config: {}, + trigger: {type: TaskTriggerType.never} + }, { + taskName: DefaultsTasks[DefaultsTasks['Video Converting']], + config: {}, + trigger: {type: TaskTriggerType.never} + }] + }, + Video: { + transcoding: { + bitRate: 5 * 1024 * 1024, + codec: 'libx264', + format: 'mp4', + fps: 25, + resolution: 720 + } + } + }; +} + diff --git a/src/frontend/app/ui/settings/settings.service.ts b/src/frontend/app/ui/settings/settings.service.ts index c32c2e20..1c60406e 100644 --- a/src/frontend/app/ui/settings/settings.service.ts +++ b/src/frontend/app/ui/settings/settings.service.ts @@ -1,10 +1,8 @@ import {Injectable} from '@angular/core'; import {BehaviorSubject} from 'rxjs'; import {NetworkService} from '../../model/network/network.service'; -import {SortingMethods} from '../../../../common/entities/SortingMethods'; -import {UserRoles} from '../../../../common/entities/UserDTO'; -import {ClientConfig} from '../../../../common/config/public/ConfigClass'; -import {IPrivateConfig, ServerConfig} from '../../../../common/config/private/IPrivateConfig'; +import {IPrivateConfig} from '../../../../common/config/private/IPrivateConfig'; +import {PrivateConfigDefaultsClass} from '../../../../common/config/private/PrivateConfigDefaultsClass'; @Injectable() export class SettingsService { @@ -12,119 +10,7 @@ export class SettingsService { private fetchingSettings = false; constructor(private _networkService: NetworkService) { - this.settings = new BehaviorSubject({ - Client: { - appVersion: '', - Search: { - enabled: true, - AutoComplete: { - enabled: true, - cacheTimeout: 1000 * 60 * 60, - maxItemsPerCategory: 5 - }, - instantSearchEnabled: true, - InstantSearchTimeout: 0, - searchCacheTimeout: 1000 * 60 * 60, - instantSearchCacheTimeout: 1000 * 60 * 60, - }, - Thumbnail: { - concurrentThumbnailGenerations: null, - iconSize: 30, - personThumbnailSize: 200, - thumbnailSizes: [] - }, - Sharing: { - enabled: true, - passwordProtected: true - }, - Map: { - enabled: true, - useImageMarkers: true, - mapProvider: ClientConfig.MapProviders.OpenStreetMap, - mapboxAccessToken: '', - customLayers: [{name: 'street', url: ''}] - }, - RandomPhoto: { - enabled: true - }, - Video: { - enabled: true - }, - MetaFile: { - enabled: true - }, - Other: { - captionFirstNaming: false, - enableCache: true, - enableOnScrollRendering: true, - enableOnScrollThumbnailPrioritising: true, - defaultPhotoSortingMethod: SortingMethods.ascDate, - NavBar: { - showItemCount: true - } - }, - Faces: { - enabled: true, - keywordsToPersons: true, - writeAccessMinRole: UserRoles.Admin - }, - urlBase: '', - publicUrl: '', - applicationTitle: '', - authenticationRequired: true, - unAuthenticatedUserRole: UserRoles.Admin, - languages: [] - }, - Server: { - Database: { - type: ServerConfig.DatabaseType.memory - }, - Log: { - level: ServerConfig.LogLevel.info, - sqlLevel: ServerConfig.SQLLogLevel.error - }, - Sharing: { - updateTimeout: 2000 - }, - imagesFolder: '', - port: 80, - host: '0.0.0.0', - Thumbnail: { - personFaceMargin: 0.1, - folder: '', - qualityPriority: true, - processingLibrary: ServerConfig.ThumbnailProcessingLib.sharp - }, - Threading: { - enable: true, - thumbnailThreads: 0 - }, - sessionTimeout: 0, - Indexing: { - cachedFolderTimeout: 0, - folderPreviewSize: 0, - reIndexingSensitivity: ServerConfig.ReIndexingSensitivity.medium, - excludeFolderList: [], - excludeFileList: [] - }, - photoMetadataSize: 512 * 1024, - Duplicates: { - listingLimit: 1000 - }, - Tasks: { - scheduled: [] - }, - Video: { - transcoding: { - bitRate: 5 * 1024 * 1024, - codec: 'libx264', - format: 'mp4', - fps: 25, - resolution: 720 - } - } - } - }); + this.settings = new BehaviorSubject(new PrivateConfigDefaultsClass()); } public async getSettings(): Promise { diff --git a/src/frontend/app/ui/settings/tasks/tasks.settings.component.html b/src/frontend/app/ui/settings/tasks/tasks.settings.component.html index fc678fda..f1154c35 100644 --- a/src/frontend/app/ui/settings/tasks/tasks.settings.component.html +++ b/src/frontend/app/ui/settings/tasks/tasks.settings.component.html @@ -115,13 +115,13 @@
- +
- +
-
- +
-
diff --git a/src/frontend/app/ui/settings/tasks/tasks.settings.component.ts b/src/frontend/app/ui/settings/tasks/tasks.settings.component.ts index f06121e9..1ac0504e 100644 --- a/src/frontend/app/ui/settings/tasks/tasks.settings.component.ts +++ b/src/frontend/app/ui/settings/tasks/tasks.settings.component.ts @@ -16,6 +16,7 @@ import { } from '../../../../../common/entities/task/TaskScheduleDTO'; import {Utils} from '../../../../../common/Utils'; import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig'; +import {ConfigTemplateEntry} from '../../../../../common/entities/task/TaskDTO'; @Component({ selector: 'app-settings-tasks', @@ -65,14 +66,9 @@ export class TasksSettingsComponent extends SettingsComponent t.Name === taskName); if (task && task.ConfigTemplate && task.ConfigTemplate.length > 0) { - const schedule = this.settings.scheduled.find(s => s.taskName === taskName); - if (schedule) { - schedule.config = schedule.config || {}; - task.ConfigTemplate.forEach(ct => schedule.config[ct.id] = ct.defaultValue); - } return task.ConfigTemplate; } return null; @@ -149,13 +145,19 @@ export class TasksSettingsComponent extends SettingsComponent{}, trigger: { type: TaskTriggerType.never } - }); + }; + + const task = this._settingsService.availableTasks.value.find(t => t.Name === taskName); + newSchedule.config = newSchedule.config || {}; + task.ConfigTemplate.forEach(ct => newSchedule.config[ct.id] = ct.defaultValue); + this.settings.scheduled.push(newSchedule); } taskTriggerTypeChanged(triggerType: TaskTriggerType, schedule: TaskScheduleDTO) {