mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-25 02:04:15 +02:00
upgrading to typeconfig2.0
This commit is contained in:
parent
1b43fb47f7
commit
4e3f464cf8
180
MANPAGE.md
Normal file
180
MANPAGE.md
Normal file
@ -0,0 +1,180 @@
|
||||
# Pigallery 2 man page
|
||||
pigallery2 uses [typeconfig](https://github.com/bpatrik/typeconfig) for configuration
|
||||
|
||||
`npm start -- --help` prints the following:
|
||||
|
||||
```bash
|
||||
Usage: <appname> [options]
|
||||
|
||||
Meta cli options:
|
||||
--help prints this manual
|
||||
--config-path sets the config file location
|
||||
--config-attachDefs prints the defaults to the config file
|
||||
--config-attachDesc prints description to the config file
|
||||
--config-rewrite-cli updates the config file with the options from cli switches
|
||||
--config-rewrite-env updates the config file with the options from environmental variables
|
||||
--config-string-enum enums are stored as string in the config file (instead of numbers)
|
||||
--config-save-if-not-exist creates config file if not exist
|
||||
--config-save-and-exist creates config file and terminates
|
||||
|
||||
<appname> can be configured through the configuration file, cli switches and environmental variables.
|
||||
All settings are case sensitive.
|
||||
Example for setting config MyConf through cli: '<appname> --MyConf=5'
|
||||
and through env variable: 'SET MyConf=5' .
|
||||
|
||||
Default values can be also overwritten by prefixing the options with 'default-',
|
||||
like '<appname> --default-MyConf=5' and 'SET default-MyConf=5'
|
||||
|
||||
App CLI options:
|
||||
--Server-sessionSecret (default: [])
|
||||
--Server-port (default: 80)
|
||||
--Server-host (default: '0.0.0.0')
|
||||
--Server-Media-folder Images are loaded from this folder (read permission required) (default: 'demo/images')
|
||||
--Server-Media-tempFolder Thumbnails, coverted photos, videos will be stored here (write permission required) (default: 'demo/tmp')
|
||||
--Server-Media-photoProcessingLibrary (default: 'sharp')
|
||||
--Server-Media-Video-transcoding-bitRate (default: 5242880)
|
||||
--Server-Media-Video-transcoding-resolution (default: 720)
|
||||
--Server-Media-Video-transcoding-fps (default: 25)
|
||||
--Server-Media-Video-transcoding-codec (default: 'libx264')
|
||||
--Server-Media-Video-transcoding-format (default: 'mp4')
|
||||
--Server-Media-Photo-Converting-onTheFly Converts photos on the fly, when they are requested. (default: true)
|
||||
--Server-Media-Photo-Converting-resolution (default: 1080)
|
||||
--Server-Media-Thumbnail-qualityPriority if true, photos will have better quality. (default: true)
|
||||
--Server-Media-Thumbnail-personFaceMargin (default: 0.6)
|
||||
--Server-Threading-enabled App can run on multiple thread (default: true)
|
||||
--Server-Threading-thumbnailThreads Number of threads that are used to generate thumbnails. If 0, number of 'CPU cores -1' threads will be used. (default: 0)
|
||||
--Server-Database-type (default: 'sqlite')
|
||||
--Server-Database-dbFolder (default: 'db')
|
||||
--Server-Database-mysql-host (default: '')
|
||||
--Server-Database-mysql-database (default: '')
|
||||
--Server-Database-mysql-username (default: '')
|
||||
--Server-Database-mysql-password (default: '')
|
||||
--Server-Sharing-updateTimeout (default: 300000)
|
||||
--Server-sessionTimeout unit: ms (default: 604800000)
|
||||
--Server-Indexing-folderPreviewSize (default: 2)
|
||||
--Server-Indexing-cachedFolderTimeout (default: 3600000)
|
||||
--Server-Indexing-reIndexingSensitivity (default: 'low')
|
||||
--Server-Indexing-excludeFolderList If an entry starts with '/' it is treated as an absolute path. If it doesn't start with '/' but contains a '/', the path is relative to the image directory. If it doesn't contain a '/', any folder with this name will be excluded. (default: [])
|
||||
--Server-Indexing-excludeFileList Any folder that contains a file with this name will be excluded from indexing. (default: [])
|
||||
--Server-photoMetadataSize only this many bites will be loaded when scanning photo for metadata (default: 524288)
|
||||
--Server-Duplicates-listingLimit (default: 1000)
|
||||
--Server-Log-level (default: 'info')
|
||||
--Server-Log-sqlLevel (default: 'error')
|
||||
--Server-Jobs-maxSavedProgress Job history size (default: 10)
|
||||
--Server-Jobs-scheduled (default: [{"name":"Indexing","jobName":"Indexing","config":{},"allowParallelRun":false,"trigger":{"type":1}},{"name":"Thumbnail Generation","jobName":"Thumbnail Generation","config":{"sizes":[240]},"allowParallelRun":false,"trigger":{"type":4,"afterScheduleName":"Indexing"}},{"name":"Photo Converting","jobName":"Photo Converting","config":{},"allowParallelRun":false,"trigger":{"type":4,"afterScheduleName":"Thumbnail Generation"}},{"name":"Video Converting","jobName":"Video Converting","config":{},"allowParallelRun":false,"trigger":{"type":4,"afterScheduleName":"Photo Converting"}},{"name":"Temp Folder Cleaning","jobName":"Temp Folder Cleaning","config":{},"allowParallelRun":false,"trigger":{"type":4,"afterScheduleName":"Photo Converting"}}])
|
||||
--Client-applicationTitle (default: 'PiGallery 2')
|
||||
--Client-publicUrl (default: '')
|
||||
--Client-urlBase (default: '')
|
||||
--Client-Search-enabled (default: true)
|
||||
--Client-Search-instantSearchEnabled (default: true)
|
||||
--Client-Search-InstantSearchTimeout (default: 3000)
|
||||
--Client-Search-instantSearchCacheTimeout (default: 3600000)
|
||||
--Client-Search-searchCacheTimeout (default: 3600000)
|
||||
--Client-Search-AutoComplete-enabled (default: true)
|
||||
--Client-Search-AutoComplete-maxItemsPerCategory (default: 5)
|
||||
--Client-Search-AutoComplete-cacheTimeout (default: 3600000)
|
||||
--Client-Sharing-enabled (default: true)
|
||||
--Client-Sharing-passwordProtected (default: true)
|
||||
--Client-Map-enabled (default: true)
|
||||
--Client-Map-useImageMarkers (default: true)
|
||||
--Client-Map-mapProvider (default: 0)
|
||||
--Client-Map-mapboxAccessToken (default: '')
|
||||
--Client-Map-customLayers (default: [{"name":"street","url":""}])
|
||||
--Client-RandomPhoto-enabled (default: true)
|
||||
--Client-Other-enableCache (default: true)
|
||||
--Client-Other-enableOnScrollRendering (default: true)
|
||||
--Client-Other-defaultPhotoSortingMethod (default: 'ascDate')
|
||||
--Client-Other-enableOnScrollThumbnailPrioritising (default: true)
|
||||
--Client-Other-NavBar-showItemCount (default: true)
|
||||
--Client-Other-captionFirstNaming (default: false)
|
||||
--Client-authenticationRequired (default: true)
|
||||
--Client-unAuthenticatedUserRole (default: 'Admin')
|
||||
--Client-Media-Thumbnail-iconSize (default: 45)
|
||||
--Client-Media-Thumbnail-personThumbnailSize (default: 200)
|
||||
--Client-Media-Thumbnail-thumbnailSizes (default: [240,480])
|
||||
--Client-Media-Video-enabled (default: true)
|
||||
--Client-Media-Photo-Converting-enabled (default: true)
|
||||
--Client-MetaFile-enabled (default: true)
|
||||
--Client-Faces-enabled (default: true)
|
||||
--Client-Faces-keywordsToPersons (default: true)
|
||||
--Client-Faces-writeAccessMinRole (default: 'Admin')
|
||||
|
||||
Environmental variables:
|
||||
Server-sessionSecret (default: [])
|
||||
Server-port (default: 80)
|
||||
PORT same as Server-port
|
||||
Server-host (default: '0.0.0.0')
|
||||
Server-Media-folder Images are loaded from this folder (read permission required) (default: 'demo/images')
|
||||
Server-Media-tempFolder Thumbnails, coverted photos, videos will be stored here (write permission required) (default: 'demo/tmp')
|
||||
Server-Media-photoProcessingLibrary (default: 'sharp')
|
||||
Server-Media-Video-transcoding-bitRate (default: 5242880)
|
||||
Server-Media-Video-transcoding-resolution (default: 720)
|
||||
Server-Media-Video-transcoding-fps (default: 25)
|
||||
Server-Media-Video-transcoding-codec (default: 'libx264')
|
||||
Server-Media-Video-transcoding-format (default: 'mp4')
|
||||
Server-Media-Photo-Converting-onTheFly Converts photos on the fly, when they are requested. (default: true)
|
||||
Server-Media-Photo-Converting-resolution (default: 1080)
|
||||
Server-Media-Thumbnail-qualityPriority if true, photos will have better quality. (default: true)
|
||||
Server-Media-Thumbnail-personFaceMargin (default: 0.6)
|
||||
Server-Threading-enabled App can run on multiple thread (default: true)
|
||||
Server-Threading-thumbnailThreads Number of threads that are used to generate thumbnails. If 0, number of 'CPU cores -1' threads will be used. (default: 0)
|
||||
Server-Database-type (default: 'sqlite')
|
||||
Server-Database-dbFolder (default: 'db')
|
||||
Server-Database-mysql-host (default: '')
|
||||
MYSQL_HOST same as Server-Database-mysql-host
|
||||
Server-Database-mysql-database (default: '')
|
||||
MYSQL_PASSWORD same as Server-Database-mysql-database
|
||||
Server-Database-mysql-username (default: '')
|
||||
MYSQL_USERNAME same as Server-Database-mysql-username
|
||||
Server-Database-mysql-password (default: '')
|
||||
MYSQL_DATABASE same as Server-Database-mysql-password
|
||||
Server-Sharing-updateTimeout (default: 300000)
|
||||
Server-sessionTimeout unit: ms (default: 604800000)
|
||||
Server-Indexing-folderPreviewSize (default: 2)
|
||||
Server-Indexing-cachedFolderTimeout (default: 3600000)
|
||||
Server-Indexing-reIndexingSensitivity (default: 'low')
|
||||
Server-Indexing-excludeFolderList If an entry starts with '/' it is treated as an absolute path. If it doesn't start with '/' but contains a '/', the path is relative to the image directory. If it doesn't contain a '/', any folder with this name will be excluded. (default: [])
|
||||
Server-Indexing-excludeFileList Any folder that contains a file with this name will be excluded from indexing. (default: [])
|
||||
Server-photoMetadataSize only this many bites will be loaded when scanning photo for metadata (default: 524288)
|
||||
Server-Duplicates-listingLimit (default: 1000)
|
||||
Server-Log-level (default: 'info')
|
||||
Server-Log-sqlLevel (default: 'error')
|
||||
Server-Jobs-maxSavedProgress Job history size (default: 10)
|
||||
Server-Jobs-scheduled (default: [{"name":"Indexing","jobName":"Indexing","config":{},"allowParallelRun":false,"trigger":{"type":1}},{"name":"Thumbnail Generation","jobName":"Thumbnail Generation","config":{"sizes":[240]},"allowParallelRun":false,"trigger":{"type":4,"afterScheduleName":"Indexing"}},{"name":"Photo Converting","jobName":"Photo Converting","config":{},"allowParallelRun":false,"trigger":{"type":4,"afterScheduleName":"Thumbnail Generation"}},{"name":"Video Converting","jobName":"Video Converting","config":{},"allowParallelRun":false,"trigger":{"type":4,"afterScheduleName":"Photo Converting"}},{"name":"Temp Folder Cleaning","jobName":"Temp Folder Cleaning","config":{},"allowParallelRun":false,"trigger":{"type":4,"afterScheduleName":"Photo Converting"}}])
|
||||
Client-applicationTitle (default: 'PiGallery 2')
|
||||
Client-publicUrl (default: '')
|
||||
Client-urlBase (default: '')
|
||||
Client-Search-enabled (default: true)
|
||||
Client-Search-instantSearchEnabled (default: true)
|
||||
Client-Search-InstantSearchTimeout (default: 3000)
|
||||
Client-Search-instantSearchCacheTimeout (default: 3600000)
|
||||
Client-Search-searchCacheTimeout (default: 3600000)
|
||||
Client-Search-AutoComplete-enabled (default: true)
|
||||
Client-Search-AutoComplete-maxItemsPerCategory (default: 5)
|
||||
Client-Search-AutoComplete-cacheTimeout (default: 3600000)
|
||||
Client-Sharing-enabled (default: true)
|
||||
Client-Sharing-passwordProtected (default: true)
|
||||
Client-Map-enabled (default: true)
|
||||
Client-Map-useImageMarkers (default: true)
|
||||
Client-Map-mapProvider (default: 0)
|
||||
Client-Map-mapboxAccessToken (default: '')
|
||||
Client-Map-customLayers (default: [{"name":"street","url":""}])
|
||||
Client-RandomPhoto-enabled (default: true)
|
||||
Client-Other-enableCache (default: true)
|
||||
Client-Other-enableOnScrollRendering (default: true)
|
||||
Client-Other-defaultPhotoSortingMethod (default: 'ascDate')
|
||||
Client-Other-enableOnScrollThumbnailPrioritising (default: true)
|
||||
Client-Other-NavBar-showItemCount (default: true)
|
||||
Client-Other-captionFirstNaming (default: false)
|
||||
Client-authenticationRequired (default: true)
|
||||
Client-unAuthenticatedUserRole (default: 'Admin')
|
||||
Client-Media-Thumbnail-iconSize (default: 45)
|
||||
Client-Media-Thumbnail-personThumbnailSize (default: 200)
|
||||
Client-Media-Thumbnail-thumbnailSizes (default: [240,480])
|
||||
Client-Media-Video-enabled (default: true)
|
||||
Client-Media-Photo-Converting-enabled (default: true)
|
||||
Client-MetaFile-enabled (default: true)
|
||||
Client-Faces-enabled (default: true)
|
||||
Client-Faces-keywordsToPersons (default: true)
|
||||
Client-Faces-writeAccessMinRole (default: 'Admin')
|
||||
```
|
@ -10,7 +10,7 @@ import {SearchTypes} from '../src/common/entities/AutoCompleteItem';
|
||||
import {Utils} from '../src/common/Utils';
|
||||
import {GalleryManager} from '../src/backend/model/database/sql/GalleryManager';
|
||||
import {DirectoryDTO} from '../src/common/entities/DirectoryDTO';
|
||||
import {ServerConfig} from '../src/common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../src/common/config/private/PrivateConfig';
|
||||
|
||||
const rimrafPR = util.promisify(rimraf);
|
||||
|
||||
|
10
gulpfile.ts
10
gulpfile.ts
@ -10,6 +10,8 @@ import * as child_process from 'child_process';
|
||||
// @ts-ignore
|
||||
import * as jeditor from 'gulp-json-editor';
|
||||
import {XLIFF} from 'xlf-google-translate';
|
||||
import {Config} from './src/common/config/private/Config';
|
||||
import {ConfigClassBuilder} from 'typeconfig/src/decorators/builders/ConfigClassBuilder';
|
||||
|
||||
const execPr = util.promisify(child_process.exec);
|
||||
|
||||
@ -342,6 +344,14 @@ gulp.task('add-translation-only', (cb) => {
|
||||
translate([lng], cb);
|
||||
});
|
||||
|
||||
gulp.task('generate-man', async (cb) => {
|
||||
let txt = '# Pigallery 2 man page\n';
|
||||
txt += 'pigallery2 uses [typeconfig](https://github.com/bpatrik/typeconfig) for configuration\n\n';
|
||||
txt += '`npm start -- --help` prints the following:\n\n';
|
||||
txt += '```bash\n' + ConfigClassBuilder.attachPrivateInterface(Config).__printMan() + '```';
|
||||
await fsp.writeFile('MANPAGE.md', txt);
|
||||
cb();
|
||||
});
|
||||
|
||||
gulp.task('add-translation', gulp.series('extract-locale', 'add-translation-only'));
|
||||
|
||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -18721,9 +18721,9 @@
|
||||
}
|
||||
},
|
||||
"typeconfig": {
|
||||
"version": "1.0.8-d",
|
||||
"resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-1.0.8-d.tgz",
|
||||
"integrity": "sha512-WmuJEs/ZcSELWjRUZCN26wYZ5hZiT2jQ3CYrWjMyv+J7o245DEM/WJ/52ThNIdLaWpdvPW6uHMZMGe3AiHkZaA==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.0.0.tgz",
|
||||
"integrity": "sha512-IwZH+P8J4qhyrOfKzJZJx6raEkaBjjZIiE+rzrWgdOhqVhO5Cv+pkOQdNo+z/Wq5wER5YWeDNX7Wdbqv0jt6IA==",
|
||||
"requires": {
|
||||
"optimist": "0.6.1"
|
||||
}
|
||||
|
@ -18,7 +18,8 @@
|
||||
"run-dev": "ng build --aot --watch --output-path=./dist --i18n-locale en --i18n-file src/frontend/translate/messages.en.xlf --i18n-missing-translation warning",
|
||||
"build-stats": "ng build --aot --prod --stats-json --output-path=./dist --i18n-locale en --i18n-file src/frontend/translate/messages.en.xlf --i18n-missing-translation warning",
|
||||
"merge-new-translation": "gulp merge-new-translation",
|
||||
"add-translation": "gulp add-translation"
|
||||
"add-translation": "gulp add-translation",
|
||||
"generate-man": "gulp generate-man"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -46,7 +47,7 @@
|
||||
"sqlite3": "4.1.1",
|
||||
"ts-exif-parser": "0.1.4",
|
||||
"ts-node-iptc": "1.0.11",
|
||||
"typeconfig": "1.0.8-d",
|
||||
"typeconfig": "2.0.0",
|
||||
"typeorm": "0.2.21",
|
||||
"winston": "2.4.4"
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as winston from 'winston';
|
||||
import {Config} from '../common/config/private/Config';
|
||||
import {ServerConfig} from '../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../common/config/private/PrivateConfig';
|
||||
|
||||
export const winstonSettings = {
|
||||
transports: [
|
||||
|
@ -1,8 +1,7 @@
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
import {Message} from '../../common/entities/Message';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
import {ConfigClass} from '../../common/config/private/ConfigClass';
|
||||
import {Config, PrivateConfigClass} from '../../common/config/private/Config';
|
||||
import {UserDTO, UserRoles} from '../../common/entities/UserDTO';
|
||||
import {NotificationManager} from '../model/NotifocationManager';
|
||||
import {Logger} from '../Logger';
|
||||
@ -61,10 +60,10 @@ export class RenderingMWs {
|
||||
}
|
||||
|
||||
|
||||
public static renderConfig(req: Request, res: Response, next: NextFunction) {
|
||||
const originalConf = Config.original();
|
||||
public static async renderConfig(req: Request, res: Response, next: NextFunction) {
|
||||
const originalConf = await Config.original();
|
||||
originalConf.Server.sessionSecret = null;
|
||||
const message = new Message<ConfigClass>(null, originalConf);
|
||||
const message = new Message<PrivateConfigClass>(null, <any>originalConf.toJSON({attachDefaults: true}));
|
||||
res.json(message);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error';
|
||||
import {ObjectManagers} from '../../model/ObjectManagers';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {ISQLGalleryManager} from '../../model/database/sql/IGalleryManager';
|
||||
import {ServerConfig} from '../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../common/config/private/PrivateConfig';
|
||||
|
||||
|
||||
export class AdminMWs {
|
||||
|
@ -6,15 +6,15 @@ import {Logger} from '../../Logger';
|
||||
import {SQLConnection} from '../../model/database/sql/SQLConnection';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {ConfigDiagnostics} from '../../model/diagnostics/ConfigDiagnostics';
|
||||
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 {ConfigClass} from '../../../common/config/private/ConfigClass';
|
||||
import {ServerConfig} from '../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../common/config/private/PrivateConfig';
|
||||
import {ClientConfig} from '../../../common/config/public/ClientConfig';
|
||||
|
||||
const LOG_TAG = '[SettingsMWs]';
|
||||
|
||||
|
||||
export class SettingsMWs {
|
||||
|
||||
public static async updateDatabaseSettings(req: Request, res: Response, next: NextFunction) {
|
||||
@ -31,7 +31,7 @@ export class SettingsMWs {
|
||||
}
|
||||
Config.Server.Database = databaseSettings;
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
original.Server.Database = databaseSettings;
|
||||
if (databaseSettings.type === ServerConfig.DatabaseType.memory) {
|
||||
original.Client.Sharing.enabled = false;
|
||||
@ -68,7 +68,7 @@ export class SettingsMWs {
|
||||
|
||||
Config.Client.Map = <ClientConfig.MapConfig>req.body.settings;
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
original.Client.Map = <ClientConfig.MapConfig>req.body.settings;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
@ -95,7 +95,7 @@ export class SettingsMWs {
|
||||
} = req.body.settings;
|
||||
|
||||
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
await ConfigDiagnostics.testClientVideoConfig(settings.client);
|
||||
await ConfigDiagnostics.testServerVideoConfig(settings.server, original);
|
||||
Config.Server.Media.Video = settings.server;
|
||||
@ -122,7 +122,7 @@ export class SettingsMWs {
|
||||
}
|
||||
|
||||
try {
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
await ConfigDiagnostics.testMetaFileConfig(<ClientConfig.MetaFileConfig>req.body.settings, original);
|
||||
|
||||
Config.Client.MetaFile = <ClientConfig.MetaFileConfig>req.body.settings;
|
||||
@ -149,7 +149,7 @@ export class SettingsMWs {
|
||||
|
||||
try {
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
await ConfigDiagnostics.testSharingConfig(<ClientConfig.SharingConfig>req.body.settings, original);
|
||||
|
||||
Config.Client.Sharing = <ClientConfig.SharingConfig>req.body.settings;
|
||||
@ -174,7 +174,7 @@ export class SettingsMWs {
|
||||
|
||||
try {
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
await ConfigDiagnostics.testRandomPhotoConfig(<ClientConfig.RandomPhotoConfig>req.body.settings, original);
|
||||
|
||||
Config.Client.RandomPhoto = <ClientConfig.RandomPhotoConfig>req.body.settings;
|
||||
@ -199,7 +199,7 @@ export class SettingsMWs {
|
||||
|
||||
try {
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
await ConfigDiagnostics.testSearchConfig(<ClientConfig.SearchConfig>req.body.settings, original);
|
||||
|
||||
Config.Client.Search = <ClientConfig.SearchConfig>req.body.settings;
|
||||
@ -224,7 +224,7 @@ export class SettingsMWs {
|
||||
|
||||
try {
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
await ConfigDiagnostics.testFacesConfig(<ClientConfig.FacesConfig>req.body.settings, original);
|
||||
|
||||
Config.Client.Faces = <ClientConfig.FacesConfig>req.body.settings;
|
||||
@ -250,7 +250,7 @@ export class SettingsMWs {
|
||||
try {
|
||||
Config.Client.authenticationRequired = <boolean>req.body.settings;
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
original.Client.authenticationRequired = <boolean>req.body.settings;
|
||||
if (original.Client.authenticationRequired === false) {
|
||||
original.Client.Sharing.enabled = false;
|
||||
@ -284,7 +284,7 @@ export class SettingsMWs {
|
||||
Config.Server.Media.Thumbnail = settings.server;
|
||||
Config.Client.Media.Thumbnail = settings.client;
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
original.Server.Media.Thumbnail = settings.server;
|
||||
original.Client.Media.Thumbnail = settings.client;
|
||||
original.save();
|
||||
@ -320,7 +320,7 @@ export class SettingsMWs {
|
||||
Config.Server.Media.Photo = settings.server;
|
||||
Config.Client.Media.Photo = settings.client;
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
original.Server.Media.photoProcessingLibrary = settings.photoProcessingLibrary;
|
||||
original.Server.Media.Photo = settings.server;
|
||||
original.Client.Media.Photo = settings.client;
|
||||
@ -353,7 +353,7 @@ export class SettingsMWs {
|
||||
Config.Client.urlBase = settings.urlBase;
|
||||
Config.Client.applicationTitle = settings.applicationTitle;
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
original.Server.port = settings.port;
|
||||
original.Server.host = settings.host;
|
||||
original.Server.Media.folder = settings.imagesFolder;
|
||||
@ -389,7 +389,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: ConfigClass = Config.original();
|
||||
const original = await Config.original();
|
||||
original.Client.Other.enableCache = settings.Client.enableCache;
|
||||
original.Client.Other.captionFirstNaming = settings.Client.captionFirstNaming;
|
||||
original.Client.Other.enableOnScrollRendering = settings.Client.enableOnScrollRendering;
|
||||
@ -398,7 +398,7 @@ export class SettingsMWs {
|
||||
original.Client.Other.NavBar.showItemCount = settings.Client.NavBar.showItemCount;
|
||||
original.Server.Threading.enabled = settings.Server.enabled;
|
||||
original.Server.Threading.thumbnailThreads = settings.Server.thumbnailThreads;
|
||||
original.save();
|
||||
await original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
@ -421,7 +421,7 @@ export class SettingsMWs {
|
||||
Config.Server.Indexing = settings;
|
||||
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
original.Server.Indexing = settings;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
@ -445,7 +445,7 @@ export class SettingsMWs {
|
||||
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const settings: ServerConfig.JobConfig = req.body.settings;
|
||||
const original = Config.original();
|
||||
const original = await Config.original();
|
||||
await ConfigDiagnostics.testTasksConfig(settings, original);
|
||||
|
||||
Config.Server.Jobs = settings;
|
||||
|
@ -7,7 +7,7 @@ import {ProjectPath} from '../../../ProjectPath';
|
||||
import {Config} from '../../../../common/config/private/Config';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {DiskMangerWorker} from '../../threading/DiskMangerWorker';
|
||||
import {ServerConfig} from '../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../common/config/private/PrivateConfig';
|
||||
|
||||
export class GalleryManager implements IGalleryManager {
|
||||
|
||||
|
@ -18,7 +18,7 @@ import {Logger} from '../../../Logger';
|
||||
import {FaceRegionEntry} from './enitites/FaceRegionEntry';
|
||||
import {ObjectManagers} from '../../ObjectManagers';
|
||||
import {DuplicatesDTO} from '../../../../common/entities/DuplicatesDTO';
|
||||
import {ServerConfig} from '../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../common/config/private/PrivateConfig';
|
||||
|
||||
const LOG_TAG = '[GalleryManager]';
|
||||
|
||||
|
@ -18,7 +18,7 @@ import {FaceRegionEntry} from './enitites/FaceRegionEntry';
|
||||
import {PersonEntry} from './enitites/PersonEntry';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import * as path from 'path';
|
||||
import {ServerConfig} from '../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../common/config/private/PrivateConfig';
|
||||
|
||||
|
||||
export class SQLConnection {
|
||||
@ -110,6 +110,10 @@ export class SQLConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public static getSQLiteDB(config: ServerConfig.DataBaseConfig) {
|
||||
return path.join(ProjectPath.getAbsolutePath(config.dbFolder), 'sqlite.db');
|
||||
}
|
||||
|
||||
private static async createConnection(options: ConnectionOptions) {
|
||||
if (options.type === 'sqlite') {
|
||||
return await createConnection(options);
|
||||
@ -185,8 +189,4 @@ export class SQLConnection {
|
||||
return driver;
|
||||
}
|
||||
|
||||
public static getSQLiteDB(config: ServerConfig.DataBaseConfig) {
|
||||
return path.join(ProjectPath.getAbsolutePath(config.dbFolder), 'sqlite.db');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {Config} from '../../../../../common/config/private/Config';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ColumnOptions} from 'typeorm/decorator/options/ColumnOptions';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
export class ColumnCharsetCS implements ColumnOptions {
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {Config, PrivateConfigClass} from '../../../common/config/private/Config';
|
||||
import {Logger} from '../../Logger';
|
||||
import {NotificationManager} from '../NotifocationManager';
|
||||
import {ProjectPath} from '../../ProjectPath';
|
||||
import {SQLConnection} from '../database/sql/SQLConnection';
|
||||
import * as fs from 'fs';
|
||||
import {ClientConfig} from '../../../common/config/public/ConfigClass';
|
||||
import {FFmpegFactory} from '../FFmpegFactory';
|
||||
import {IPrivateConfig, ServerConfig} from '../../../common/config/private/IPrivateConfig';
|
||||
import {ClientConfig} from '../../../common/config/public/ClientConfig';
|
||||
import {ServerConfig} from '../../../common/config/private/PrivateConfig';
|
||||
import MapLayers = ClientConfig.MapLayers;
|
||||
|
||||
const LOG_TAG = '[ConfigDiagnostics]';
|
||||
|
||||
@ -39,7 +40,7 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
|
||||
|
||||
static async testMetaFileConfig(metaFileConfig: ClientConfig.MetaFileConfig, config: IPrivateConfig) {
|
||||
static async testMetaFileConfig(metaFileConfig: ClientConfig.MetaFileConfig, config: PrivateConfig) {
|
||||
if (metaFileConfig.enabled === true &&
|
||||
config.Client.Map.enabled === false) {
|
||||
throw new Error('*.gpx meta files are not supported without MAP');
|
||||
@ -72,7 +73,7 @@ export class ConfigDiagnostics {
|
||||
});
|
||||
}
|
||||
|
||||
static async testServerVideoConfig(videoConfig: ServerConfig.VideoConfig, config: IPrivateConfig) {
|
||||
static async testServerVideoConfig(videoConfig: ServerConfig.VideoConfig, config: PrivateConfig) {
|
||||
if (config.Client.Media.Video.enabled === true) {
|
||||
if (videoConfig.transcoding.fps <= 0) {
|
||||
throw new Error('fps should be grater than 0');
|
||||
@ -157,11 +158,11 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
|
||||
|
||||
static async testTasksConfig(task: ServerConfig.JobConfig, config: IPrivateConfig) {
|
||||
static async testTasksConfig(task: ServerConfig.JobConfig, config: PrivateConfig) {
|
||||
|
||||
}
|
||||
|
||||
static async testFacesConfig(faces: ClientConfig.FacesConfig, config: IPrivateConfig) {
|
||||
static async testFacesConfig(faces: ClientConfig.FacesConfig, config: PrivateConfig) {
|
||||
if (faces.enabled === true) {
|
||||
if (config.Server.Database.type === ServerConfig.DatabaseType.memory) {
|
||||
throw new Error('Memory Database do not support faces');
|
||||
@ -172,7 +173,7 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
}
|
||||
|
||||
static async testSearchConfig(search: ClientConfig.SearchConfig, config: IPrivateConfig) {
|
||||
static async testSearchConfig(search: ClientConfig.SearchConfig, config: PrivateConfig) {
|
||||
if (search.enabled === true &&
|
||||
config.Server.Database.type === ServerConfig.DatabaseType.memory) {
|
||||
throw new Error('Memory Database do not support searching');
|
||||
@ -180,7 +181,7 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
|
||||
|
||||
static async testSharingConfig(sharing: ClientConfig.SharingConfig, config: IPrivateConfig) {
|
||||
static async testSharingConfig(sharing: ClientConfig.SharingConfig, config: PrivateConfig) {
|
||||
if (sharing.enabled === true &&
|
||||
config.Server.Database.type === ServerConfig.DatabaseType.memory) {
|
||||
throw new Error('Memory Database do not support sharing');
|
||||
@ -191,7 +192,7 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
}
|
||||
|
||||
static async testRandomPhotoConfig(sharing: ClientConfig.RandomPhotoConfig, config: IPrivateConfig) {
|
||||
static async testRandomPhotoConfig(sharing: ClientConfig.RandomPhotoConfig, config: PrivateConfig) {
|
||||
if (sharing.enabled === true &&
|
||||
config.Server.Database.type === ServerConfig.DatabaseType.memory) {
|
||||
throw new Error('Memory Database do not support random photo');
|
||||
@ -212,7 +213,7 @@ export class ConfigDiagnostics {
|
||||
throw new Error('Custom maps need at least one valid layer');
|
||||
}
|
||||
if (map.mapProvider === ClientConfig.MapProviders.Custom) {
|
||||
map.customLayers.forEach(l => {
|
||||
map.customLayers.forEach((l: MapLayers) => {
|
||||
if (!l.url || l.url.length === 0) {
|
||||
throw new Error('Custom maps url need to be a valid layer');
|
||||
}
|
||||
@ -231,7 +232,7 @@ export class ConfigDiagnostics {
|
||||
Logger.warn(LOG_TAG, '[SQL error]', err.toString());
|
||||
Logger.warn(LOG_TAG, 'Error during initializing SQL falling back temporally to memory DB');
|
||||
NotificationManager.warning('Error during initializing SQL falling back temporally to memory DB', err.toString());
|
||||
Config.setDatabaseType(ServerConfig.DatabaseType.memory);
|
||||
Config.Server.Database.type = ServerConfig.DatabaseType.memory;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,9 @@ import {Config} from '../../../common/config/private/Config';
|
||||
import {ThumbnailTH} from '../threading/ThreadPool';
|
||||
import {PhotoWorker, RendererInput, ThumbnailSourceType} from '../threading/PhotoWorker';
|
||||
import {ITaskExecuter, TaskExecuter} from '../threading/TaskExecuter';
|
||||
import {ServerConfig} from '../../../common/config/private/IPrivateConfig';
|
||||
import {FaceRegion, PhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {SupportedFormats} from '../../../common/SupportedFormats';
|
||||
import {ServerConfig} from '../../../common/config/private/PrivateConfig';
|
||||
|
||||
|
||||
export class PhotoProcessing {
|
||||
|
@ -2,7 +2,7 @@ import {ObjectManagers} from '../../ObjectManagers';
|
||||
import {Config} from '../../../../common/config/private/Config';
|
||||
import {ConfigTemplateEntry, DefaultsJobs} from '../../../../common/entities/job/JobDTO';
|
||||
import {Job} from './Job';
|
||||
import {ServerConfig} from '../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../common/config/private/PrivateConfig';
|
||||
|
||||
|
||||
export class DBRestJob extends Job {
|
||||
|
@ -5,7 +5,6 @@ import {DiskManager} from '../../DiskManger';
|
||||
import {DiskMangerWorker} from '../../threading/DiskMangerWorker';
|
||||
import {Logger} from '../../../Logger';
|
||||
import {Config} from '../../../../common/config/private/Config';
|
||||
import {ServerConfig} from '../../../../common/config/private/IPrivateConfig';
|
||||
import {FileDTO} from '../../../../common/entities/FileDTO';
|
||||
import {SQLConnection} from '../../database/sql/SQLConnection';
|
||||
import {MediaEntity} from '../../database/sql/enitites/MediaEntity';
|
||||
@ -13,6 +12,7 @@ import {PhotoEntity} from '../../database/sql/enitites/PhotoEntity';
|
||||
import {VideoEntity} from '../../database/sql/enitites/VideoEntity';
|
||||
import {backendTexts} from '../../../../common/BackendTexts';
|
||||
import {ProjectPath} from '../../../ProjectPath';
|
||||
import {ServerConfig} from '../../../../common/config/private/PrivateConfig';
|
||||
|
||||
declare var global: NodeJS.Global;
|
||||
|
||||
|
@ -3,8 +3,8 @@ import * as path from 'path';
|
||||
import {Config} from '../../../../common/config/private/Config';
|
||||
import {Job} from './Job';
|
||||
import {ConfigTemplateEntry, DefaultsJobs} from '../../../../common/entities/job/JobDTO';
|
||||
import {ServerConfig} from '../../../../common/config/private/IPrivateConfig';
|
||||
import {JobProgressStates} from '../../../../common/entities/job/JobProgressDTO';
|
||||
import {ServerConfig} from '../../../../common/config/private/PrivateConfig';
|
||||
|
||||
|
||||
export class IndexingJob extends Job {
|
||||
|
@ -3,7 +3,7 @@ import {Dimensions, State} from 'gm';
|
||||
import {Logger} from '../../Logger';
|
||||
import {FfmpegCommand, FfprobeData} from 'fluent-ffmpeg';
|
||||
import {FFmpegFactory} from '../FFmpegFactory';
|
||||
import {ServerConfig} from '../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../common/config/private/PrivateConfig';
|
||||
|
||||
export class PhotoWorker {
|
||||
|
||||
|
@ -2,7 +2,7 @@ import {Logger} from '../../Logger';
|
||||
import {promises as fsp} from 'fs';
|
||||
import {FfmpegCommand} from 'fluent-ffmpeg';
|
||||
import {FFmpegFactory} from '../FFmpegFactory';
|
||||
import {ServerConfig} from '../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../common/config/private/PrivateConfig';
|
||||
|
||||
|
||||
export interface VideoConverterInput {
|
||||
|
@ -3,7 +3,7 @@ import {Logger} from '../../Logger';
|
||||
import {PhotoWorker, RendererInput} from './PhotoWorker';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {ServerConfig} from '../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../common/config/private/PrivateConfig';
|
||||
|
||||
declare var process: NodeJS.Process;
|
||||
declare var global: NodeJS.Global;
|
||||
|
@ -82,7 +82,7 @@ export class PublicRouter {
|
||||
res.tpl.user.csrfToken = req.csrfToken();
|
||||
}
|
||||
}
|
||||
res.tpl.clientConfig = Config.Client;
|
||||
res.tpl.clientConfig = {Client: Config.Client};
|
||||
|
||||
return next();
|
||||
});
|
||||
|
@ -1,3 +1,4 @@
|
||||
import {Config} from '../common/config/private/Config';
|
||||
import * as _express from 'express';
|
||||
import {Request} from 'express';
|
||||
import * as _bodyParser from 'body-parser';
|
||||
@ -8,19 +9,18 @@ import {Server as HttpServer} from 'http';
|
||||
import * as locale from 'locale';
|
||||
import {ObjectManagers} from './model/ObjectManagers';
|
||||
import {Logger} from './Logger';
|
||||
import {Config} from '../common/config/private/Config';
|
||||
import {LoggerRouter} from './routes/LoggerRouter';
|
||||
import {DiskManager} from './model/DiskManger';
|
||||
import {ConfigDiagnostics} from './model/diagnostics/ConfigDiagnostics';
|
||||
import {Localizations} from './model/Localizations';
|
||||
import {CookieNames} from '../common/CookieNames';
|
||||
import {Router} from './routes/Router';
|
||||
import {ServerConfig} from '../common/config/private/IPrivateConfig';
|
||||
import {PhotoProcessing} from './model/fileprocessing/PhotoProcessing';
|
||||
import * as _csrf from 'csurf';
|
||||
import * as unless from 'express-unless';
|
||||
import {Event} from '../common/event/Event';
|
||||
import {QueryParams} from '../common/QueryParams';
|
||||
import {ServerConfig} from '../common/config/private/PrivateConfig';
|
||||
|
||||
const _session = require('cookie-session');
|
||||
|
||||
|
@ -1,5 +1,55 @@
|
||||
import {ConfigClass} from './ConfigClass';
|
||||
import {IPrivateConfig, ServerConfig} from './PrivateConfig';
|
||||
import {ClientConfig} from '../public/ClientConfig';
|
||||
import * as crypto from 'crypto';
|
||||
import * as path from 'path';
|
||||
import {ConfigClass} from 'typeconfig/src/decorators/class/ConfigClass';
|
||||
import {ConfigProperty} from 'typeconfig/src/decorators/property/ConfigPropoerty';
|
||||
import {IConfigClass} from 'typeconfig/src/decorators/class/IConfigClass';
|
||||
import {ConfigClassBuilder} from 'typeconfig/src/decorators/builders/ConfigClassBuilder';
|
||||
|
||||
|
||||
export let Config = new ConfigClass();
|
||||
Config.load();
|
||||
@ConfigClass({
|
||||
configPath: path.join(__dirname, './../../../../config.json'),
|
||||
saveIfNotExist: true,
|
||||
attachDescription: true,
|
||||
enumsAsString: true,
|
||||
cli: {
|
||||
enable: {
|
||||
configPath: true,
|
||||
attachDefaults: true,
|
||||
attachDescription: true,
|
||||
rewriteCLIConfig: true,
|
||||
rewriteENVConfig: true,
|
||||
enumsAsString: true,
|
||||
saveIfNotExist: true,
|
||||
exitOnConfig: true
|
||||
},
|
||||
defaults: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
})
|
||||
export class PrivateConfigClass implements IPrivateConfig {
|
||||
@ConfigProperty()
|
||||
Server: ServerConfig.Config = new ServerConfig.Config();
|
||||
@ConfigProperty()
|
||||
Client: ClientConfig.Config = new ClientConfig.Config();
|
||||
|
||||
constructor() {
|
||||
if (!this.Server.sessionSecret || this.Server.sessionSecret.length === 0) {
|
||||
this.Server.sessionSecret = [crypto.randomBytes(256).toString('hex'),
|
||||
crypto.randomBytes(256).toString('hex'),
|
||||
crypto.randomBytes(256).toString('hex')];
|
||||
}
|
||||
}
|
||||
|
||||
async original(): Promise<PrivateConfigClass & IConfigClass> {
|
||||
const pc = ConfigClassBuilder.attachInterface(new PrivateConfigClass());
|
||||
await pc.load();
|
||||
return pc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const Config = ConfigClassBuilder.attachInterface(new PrivateConfigClass());
|
||||
Config.loadSync();
|
||||
|
@ -1,98 +0,0 @@
|
||||
import {IPrivateConfig, ServerConfig} from './IPrivateConfig';
|
||||
import * as path from 'path';
|
||||
import * as crypto from 'crypto';
|
||||
import {ConfigLoader} from 'typeconfig';
|
||||
import {Utils} from '../../Utils';
|
||||
import {UserRoles} from '../../entities/UserDTO';
|
||||
import {PrivateConfigDefaultsClass} from './PrivateConfigDefaultsClass';
|
||||
|
||||
declare var process: NodeJS.Process;
|
||||
|
||||
let CONFIG_PATH = path.join(__dirname, './../../../../config.json');
|
||||
// TODO: refactor this
|
||||
let configPath = process.argv.find(s => s.startsWith('--config-path='));
|
||||
if (configPath) {
|
||||
configPath = configPath.replace('--config-path=', '');
|
||||
if (path.isAbsolute(configPath)) {
|
||||
CONFIG_PATH = configPath;
|
||||
} else {
|
||||
CONFIG_PATH = path.join(__dirname, './../../../../', configPath);
|
||||
}
|
||||
console.log('using config path:' + CONFIG_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* This configuration will be only at backend
|
||||
*/
|
||||
export class ConfigClass extends PrivateConfigDefaultsClass implements IPrivateConfig {
|
||||
|
||||
|
||||
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, 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']],
|
||||
process.argv.indexOf('--force-rewrite-config') !== -1);
|
||||
this.removeComment();
|
||||
|
||||
if (process.argv.indexOf('--config-only') !== -1) {
|
||||
console.log('started with \'--config-only\' flag. Saving config and exiting.');
|
||||
process.exit();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (Array.isArray(this.Server.sessionSecret) === false) {
|
||||
// if not secret is set, generate one randomly
|
||||
this.Server.sessionSecret = [crypto.randomBytes(256).toString('hex'),
|
||||
crypto.randomBytes(256).toString('hex'),
|
||||
crypto.randomBytes(256).toString('hex')];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public save() {
|
||||
try {
|
||||
this.addComment();
|
||||
ConfigLoader.saveConfigFile(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() {
|
||||
(<any>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 (<any>this)['__NOTE'];
|
||||
}
|
||||
}
|
||||
|
@ -1,137 +0,0 @@
|
||||
import {ClientConfig} from '../public/ConfigClass';
|
||||
import {JobScheduleDTO} from '../../entities/job/JobScheduleDTO';
|
||||
|
||||
export module ServerConfig {
|
||||
export enum DatabaseType {
|
||||
memory = 1, mysql = 2, sqlite = 3
|
||||
}
|
||||
|
||||
export enum LogLevel {
|
||||
error = 1, warn = 2, info = 3, verbose = 4, debug = 5, silly = 6
|
||||
}
|
||||
|
||||
export enum SQLLogLevel {
|
||||
none = 1, error = 2, all = 3
|
||||
}
|
||||
|
||||
export enum PhotoProcessingLib {
|
||||
sharp = 3,
|
||||
Jimp = 1,
|
||||
gm = 2,
|
||||
}
|
||||
|
||||
export interface MySQLConfig {
|
||||
host: string;
|
||||
database: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
/*
|
||||
export interface SQLiteConfig {
|
||||
}
|
||||
|
||||
export interface MemoryConfig {
|
||||
}*/
|
||||
|
||||
export interface DataBaseConfig {
|
||||
type: DatabaseType;
|
||||
dbFolder: string;
|
||||
mysql?: MySQLConfig;
|
||||
// sqlite?: SQLiteConfig;
|
||||
// memory?: MemoryConfig;
|
||||
}
|
||||
|
||||
export interface ThumbnailConfig {
|
||||
qualityPriority: boolean;
|
||||
personFaceMargin: number; // in ration [0-1]
|
||||
}
|
||||
|
||||
export interface SharingConfig {
|
||||
updateTimeout: number;
|
||||
}
|
||||
|
||||
export enum ReIndexingSensitivity {
|
||||
low = 1, medium = 2, high = 3
|
||||
}
|
||||
|
||||
export interface IndexingConfig {
|
||||
folderPreviewSize: number;
|
||||
cachedFolderTimeout: number; // Do not rescans the folder if seems ok
|
||||
reIndexingSensitivity: ReIndexingSensitivity;
|
||||
excludeFolderList: string[];
|
||||
excludeFileList: string[];
|
||||
}
|
||||
|
||||
export interface ThreadingConfig {
|
||||
enabled: boolean;
|
||||
thumbnailThreads: number;
|
||||
}
|
||||
|
||||
export interface DuplicatesConfig {
|
||||
listingLimit: number; // maximum number of duplicates to list
|
||||
}
|
||||
|
||||
export interface LogConfig {
|
||||
level: LogLevel;
|
||||
sqlLevel: SQLLogLevel;
|
||||
}
|
||||
|
||||
export interface JobConfig {
|
||||
maxSavedProgress: number;
|
||||
scheduled: JobScheduleDTO[];
|
||||
}
|
||||
|
||||
export type codecType = 'libvpx-vp9' | 'libx264' | 'libvpx' | 'libx265';
|
||||
export type resolutionType = 240 | 360 | 480 | 720 | 1080 | 1440 | 2160 | 4320;
|
||||
export type formatType = 'mp4' | 'webm';
|
||||
|
||||
export interface VideoConfig {
|
||||
transcoding: {
|
||||
bitRate: number,
|
||||
resolution: resolutionType,
|
||||
fps: number,
|
||||
codec: codecType,
|
||||
format: formatType
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export interface PhotoConfig {
|
||||
Converting: {
|
||||
onTheFly: boolean;
|
||||
resolution: resolutionType
|
||||
};
|
||||
}
|
||||
|
||||
export interface MediaConfig {
|
||||
folder: string;
|
||||
tempFolder: string;
|
||||
photoProcessingLibrary: PhotoProcessingLib;
|
||||
Video: VideoConfig;
|
||||
Photo: PhotoConfig;
|
||||
Thumbnail: ThumbnailConfig;
|
||||
}
|
||||
|
||||
|
||||
export interface Config {
|
||||
sessionSecret: string[];
|
||||
port: number;
|
||||
host: string;
|
||||
Media: MediaConfig;
|
||||
Threading: ThreadingConfig;
|
||||
Database: DataBaseConfig;
|
||||
Sharing: SharingConfig;
|
||||
sessionTimeout: number; // in ms
|
||||
Indexing: IndexingConfig;
|
||||
photoMetadataSize: number; // only this many bites will be loaded when scanning photo for metadata
|
||||
Duplicates: DuplicatesConfig;
|
||||
Log: LogConfig;
|
||||
Jobs: JobConfig;
|
||||
}
|
||||
}
|
||||
|
||||
export interface IPrivateConfig {
|
||||
Server: ServerConfig.Config;
|
||||
Client: ClientConfig.Config;
|
||||
}
|
325
src/common/config/private/PrivateConfig.ts
Normal file
325
src/common/config/private/PrivateConfig.ts
Normal file
@ -0,0 +1,325 @@
|
||||
/* tslint:disable:no-inferrable-types */
|
||||
import 'reflect-metadata';
|
||||
import {DefaultsJobs} from '../../entities/job/JobDTO';
|
||||
import {JobScheduleDTO, JobTrigger, JobTriggerType} from '../../entities/job/JobScheduleDTO';
|
||||
import {ClientConfig} from '../public/ClientConfig';
|
||||
import { SubConfigClass } from 'typeconfig/src/decorators/class/SubConfigClass';
|
||||
import { ConfigProperty } from 'typeconfig/src/decorators/property/ConfigPropoerty';
|
||||
|
||||
export module ServerConfig {
|
||||
export enum DatabaseType {
|
||||
memory = 1, mysql = 2, sqlite = 3
|
||||
}
|
||||
|
||||
export enum LogLevel {
|
||||
error = 1, warn = 2, info = 3, verbose = 4, debug = 5, silly = 6
|
||||
}
|
||||
|
||||
export enum SQLLogLevel {
|
||||
none = 1, error = 2, all = 3
|
||||
}
|
||||
|
||||
export enum PhotoProcessingLib {
|
||||
sharp = 3,
|
||||
Jimp = 1,
|
||||
gm = 2,
|
||||
}
|
||||
|
||||
export enum ReIndexingSensitivity {
|
||||
low = 1, medium = 2, high = 3
|
||||
}
|
||||
|
||||
|
||||
export type codecType = 'libvpx-vp9' | 'libx264' | 'libvpx' | 'libx265';
|
||||
export type resolutionType = 240 | 360 | 480 | 720 | 1080 | 1440 | 2160 | 4320;
|
||||
export type formatType = 'mp4' | 'webm';
|
||||
|
||||
@SubConfigClass()
|
||||
export class MySQLConfig {
|
||||
@ConfigProperty({envAlias: 'MYSQL_HOST'})
|
||||
host: string = '';
|
||||
@ConfigProperty({envAlias: 'MYSQL_PASSWORD'})
|
||||
database: string = '';
|
||||
@ConfigProperty({envAlias: 'MYSQL_USERNAME'})
|
||||
username: string = '';
|
||||
@ConfigProperty({envAlias: 'MYSQL_DATABASE'})
|
||||
password: string = '';
|
||||
}
|
||||
|
||||
|
||||
@SubConfigClass()
|
||||
export class DataBaseConfig {
|
||||
@ConfigProperty<DatabaseType, IPrivateConfig>({
|
||||
type: DatabaseType,
|
||||
onNewValue: (value, config) => {
|
||||
if (value === ServerConfig.DatabaseType.memory) {
|
||||
config.Client.Search.enabled = false;
|
||||
config.Client.Sharing.enabled = false;
|
||||
}
|
||||
}
|
||||
})
|
||||
type: DatabaseType = DatabaseType.sqlite;
|
||||
|
||||
@ConfigProperty()
|
||||
dbFolder: string = 'db';
|
||||
|
||||
@ConfigProperty()
|
||||
mysql?: MySQLConfig = new MySQLConfig();
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class ThumbnailConfig {
|
||||
@ConfigProperty({description: 'if true, photos will have better quality.'})
|
||||
qualityPriority: boolean = true;
|
||||
@ConfigProperty({type: 'ratio'})
|
||||
personFaceMargin: number = 0.6; // in ration [0-1]
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class SharingConfig {
|
||||
@ConfigProperty()
|
||||
updateTimeout: number = 1000 * 60 * 5;
|
||||
}
|
||||
|
||||
|
||||
@SubConfigClass()
|
||||
export class IndexingConfig {
|
||||
@ConfigProperty()
|
||||
folderPreviewSize: number = 2;
|
||||
@ConfigProperty()
|
||||
cachedFolderTimeout: number = 1000 * 60 * 60; // Do not rescans the folder if seems ok
|
||||
@ConfigProperty({type: ReIndexingSensitivity})
|
||||
reIndexingSensitivity: ReIndexingSensitivity = ReIndexingSensitivity.low;
|
||||
@ConfigProperty({
|
||||
arrayType: String,
|
||||
description: 'If an entry starts with \'/\' it is treated as an absolute path.' +
|
||||
' If it doesn\'t start with \'/\' but contains a \'/\', the path is relative to the image directory.' +
|
||||
' If it doesn\'t contain a \'/\', any folder with this name will be excluded.'
|
||||
})
|
||||
excludeFolderList: string[] = [];
|
||||
@ConfigProperty({arrayType: String, description: 'Any folder that contains a file with this name will be excluded from indexing.'})
|
||||
excludeFileList: string[] = [];
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class ThreadingConfig {
|
||||
@ConfigProperty({description: 'App can run on multiple thread'})
|
||||
enabled: boolean = true;
|
||||
@ConfigProperty({description: 'Number of threads that are used to generate thumbnails. If 0, number of \'CPU cores -1\' threads will be used.'})
|
||||
thumbnailThreads: number = 0; // if zero-> CPU count -1
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class DuplicatesConfig {
|
||||
@ConfigProperty()
|
||||
listingLimit: number = 1000; // maximum number of duplicates to list
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class LogConfig {
|
||||
@ConfigProperty({type: LogLevel})
|
||||
level: LogLevel = LogLevel.info;
|
||||
@ConfigProperty({type: SQLLogLevel})
|
||||
sqlLevel: SQLLogLevel = SQLLogLevel.error;
|
||||
}
|
||||
|
||||
|
||||
@SubConfigClass()
|
||||
export class NeverJobTrigger implements JobTrigger {
|
||||
@ConfigProperty({type: JobTriggerType})
|
||||
readonly type = JobTriggerType.never;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class ScheduledJobTrigger implements JobTrigger {
|
||||
@ConfigProperty({type: JobTriggerType})
|
||||
readonly type = JobTriggerType.scheduled;
|
||||
|
||||
@ConfigProperty()
|
||||
time: number; // data time
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class PeriodicJobTrigger implements JobTrigger {
|
||||
@ConfigProperty({type: JobTriggerType})
|
||||
readonly type = JobTriggerType.periodic;
|
||||
@ConfigProperty()
|
||||
periodicity: number; // 0-6: week days 7 every day
|
||||
@ConfigProperty()
|
||||
atTime: number; // day time
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class AfterJobTrigger implements JobTrigger {
|
||||
|
||||
@ConfigProperty({type: JobTriggerType})
|
||||
readonly type = JobTriggerType.after;
|
||||
@ConfigProperty()
|
||||
afterScheduleName: string; // runs after schedule
|
||||
|
||||
constructor(afterScheduleName: string) {
|
||||
this.afterScheduleName = afterScheduleName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SubConfigClass()
|
||||
export class JobScheduleConfig implements JobScheduleDTO {
|
||||
|
||||
@ConfigProperty()
|
||||
name: string;
|
||||
@ConfigProperty()
|
||||
jobName: string;
|
||||
@ConfigProperty()
|
||||
config: any = {};
|
||||
@ConfigProperty()
|
||||
allowParallelRun: boolean;
|
||||
@ConfigProperty({
|
||||
typeBuilder: (v: JobTrigger) => {
|
||||
switch (v.type) {
|
||||
case JobTriggerType.after:
|
||||
return AfterJobTrigger;
|
||||
case JobTriggerType.never:
|
||||
return NeverJobTrigger;
|
||||
case JobTriggerType.scheduled:
|
||||
return ScheduledJobTrigger;
|
||||
case JobTriggerType.periodic:
|
||||
return PeriodicJobTrigger;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
})
|
||||
trigger: AfterJobTrigger | NeverJobTrigger | PeriodicJobTrigger | ScheduledJobTrigger;
|
||||
|
||||
constructor(name: string, jobName: string, allowParallelRun: boolean,
|
||||
trigger: AfterJobTrigger | NeverJobTrigger | PeriodicJobTrigger | ScheduledJobTrigger, config: any) {
|
||||
this.name = name;
|
||||
this.jobName = jobName;
|
||||
this.config = config;
|
||||
this.allowParallelRun = allowParallelRun;
|
||||
this.trigger = trigger;
|
||||
}
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class JobConfig {
|
||||
@ConfigProperty({type: 'integer', description: 'Job history size'})
|
||||
maxSavedProgress: number = 10;
|
||||
@ConfigProperty({arrayType: JobScheduleConfig})
|
||||
scheduled: JobScheduleConfig[] = [
|
||||
new JobScheduleConfig(DefaultsJobs[DefaultsJobs.Indexing],
|
||||
DefaultsJobs[DefaultsJobs.Indexing],
|
||||
false,
|
||||
new NeverJobTrigger(), {}
|
||||
),
|
||||
new JobScheduleConfig(DefaultsJobs[DefaultsJobs['Thumbnail Generation']],
|
||||
DefaultsJobs[DefaultsJobs['Thumbnail Generation']],
|
||||
false,
|
||||
new AfterJobTrigger(DefaultsJobs[DefaultsJobs.Indexing]), {sizes: [240]}
|
||||
),
|
||||
new JobScheduleConfig(DefaultsJobs[DefaultsJobs['Photo Converting']],
|
||||
DefaultsJobs[DefaultsJobs['Photo Converting']],
|
||||
false,
|
||||
new AfterJobTrigger(DefaultsJobs[DefaultsJobs['Thumbnail Generation']]), {}
|
||||
),
|
||||
new JobScheduleConfig(DefaultsJobs[DefaultsJobs['Video Converting']],
|
||||
DefaultsJobs[DefaultsJobs['Video Converting']],
|
||||
false,
|
||||
new AfterJobTrigger(DefaultsJobs[DefaultsJobs['Photo Converting']]), {}
|
||||
),
|
||||
new JobScheduleConfig(DefaultsJobs[DefaultsJobs['Temp Folder Cleaning']],
|
||||
DefaultsJobs[DefaultsJobs['Temp Folder Cleaning']],
|
||||
false,
|
||||
new AfterJobTrigger(DefaultsJobs[DefaultsJobs['Photo Converting']]), {}
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@SubConfigClass()
|
||||
export class VideoTranscodingConfig {
|
||||
@ConfigProperty({type: 'unsignedInt'})
|
||||
bitRate: number = 5 * 1024 * 1024;
|
||||
@ConfigProperty({type: 'unsignedInt'})
|
||||
resolution: resolutionType = 720;
|
||||
@ConfigProperty({type: 'positiveFloat'})
|
||||
fps: number = 25;
|
||||
@ConfigProperty()
|
||||
codec: codecType = 'libx264';
|
||||
@ConfigProperty()
|
||||
format: formatType = 'mp4';
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class VideoConfig {
|
||||
@ConfigProperty()
|
||||
transcoding: VideoTranscodingConfig = new VideoTranscodingConfig();
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class PhotoConvertingConfig {
|
||||
@ConfigProperty({description: 'Converts photos on the fly, when they are requested.'})
|
||||
onTheFly: boolean = true;
|
||||
@ConfigProperty({type: 'unsignedInt'})
|
||||
resolution: resolutionType = 1080;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class PhotoConfig {
|
||||
@ConfigProperty()
|
||||
Converting: PhotoConvertingConfig = new PhotoConvertingConfig();
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class MediaConfig {
|
||||
@ConfigProperty({description: 'Images are loaded from this folder (read permission required)'})
|
||||
folder: string = 'demo/images';
|
||||
@ConfigProperty({description: 'Thumbnails, coverted photos, videos will be stored here (write permission required)'})
|
||||
tempFolder: string = 'demo/tmp';
|
||||
@ConfigProperty({type: ServerConfig.PhotoProcessingLib})
|
||||
photoProcessingLibrary: PhotoProcessingLib = ServerConfig.PhotoProcessingLib.sharp;
|
||||
@ConfigProperty()
|
||||
Video: VideoConfig = new VideoConfig();
|
||||
@ConfigProperty()
|
||||
Photo: PhotoConfig = new PhotoConfig();
|
||||
@ConfigProperty()
|
||||
Thumbnail: ThumbnailConfig = new ThumbnailConfig();
|
||||
}
|
||||
|
||||
|
||||
@SubConfigClass()
|
||||
export class Config {
|
||||
@ConfigProperty({arrayType: String})
|
||||
sessionSecret: string[] = [];
|
||||
@ConfigProperty({type: 'unsignedInt', envAlias: 'PORT'})
|
||||
port: number = 80;
|
||||
@ConfigProperty()
|
||||
host: string = '0.0.0.0';
|
||||
@ConfigProperty()
|
||||
Media: MediaConfig = new MediaConfig();
|
||||
@ConfigProperty()
|
||||
Threading: ThreadingConfig = new ThreadingConfig();
|
||||
@ConfigProperty()
|
||||
Database: DataBaseConfig = new DataBaseConfig();
|
||||
@ConfigProperty()
|
||||
Sharing: SharingConfig = new SharingConfig();
|
||||
@ConfigProperty({description: 'unit: ms'})
|
||||
sessionTimeout: number = 1000 * 60 * 60 * 24 * 7; // in ms
|
||||
@ConfigProperty()
|
||||
Indexing: IndexingConfig = new IndexingConfig();
|
||||
@ConfigProperty({type: 'unsignedInt', description: 'only this many bites will be loaded when scanning photo for metadata'})
|
||||
photoMetadataSize: number = 512 * 1024; // only this many bites will be loaded when scanning photo for metadata
|
||||
@ConfigProperty()
|
||||
Duplicates: DuplicatesConfig = new DuplicatesConfig();
|
||||
@ConfigProperty()
|
||||
Log: LogConfig = new LogConfig();
|
||||
@ConfigProperty()
|
||||
Jobs: JobConfig = new JobConfig();
|
||||
}
|
||||
}
|
||||
|
||||
export interface IPrivateConfig {
|
||||
Server: ServerConfig.Config;
|
||||
Client: ClientConfig.Config;
|
||||
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
import {PublicConfigClass} from '../public/ConfigClass';
|
||||
import {IPrivateConfig, ServerConfig} from './IPrivateConfig';
|
||||
import {JobTriggerType} from '../../entities/job/JobScheduleDTO';
|
||||
import {DefaultsJobs} from '../../entities/job/JobDTO';
|
||||
|
||||
/**
|
||||
* This configuration will be only at backend
|
||||
*/
|
||||
export class PrivateConfigDefaultsClass extends PublicConfigClass implements IPrivateConfig {
|
||||
|
||||
public Server: ServerConfig.Config = {
|
||||
port: 80,
|
||||
sessionSecret: null,
|
||||
host: '0.0.0.0',
|
||||
Media: {
|
||||
folder: 'demo/images',
|
||||
tempFolder: 'demo/tmp',
|
||||
photoProcessingLibrary: ServerConfig.PhotoProcessingLib.sharp,
|
||||
Thumbnail: {
|
||||
qualityPriority: true,
|
||||
personFaceMargin: 0.6
|
||||
},
|
||||
Photo: {
|
||||
Converting: {
|
||||
onTheFly: true,
|
||||
resolution: 1080
|
||||
}
|
||||
},
|
||||
Video: {
|
||||
transcoding: {
|
||||
bitRate: 5 * 1024 * 1024,
|
||||
codec: 'libx264',
|
||||
format: 'mp4',
|
||||
fps: 25,
|
||||
resolution: 720
|
||||
}
|
||||
}
|
||||
},
|
||||
Log: {
|
||||
level: ServerConfig.LogLevel.info,
|
||||
sqlLevel: ServerConfig.SQLLogLevel.error
|
||||
},
|
||||
sessionTimeout: 1000 * 60 * 60 * 24 * 7,
|
||||
photoMetadataSize: 512 * 1024,
|
||||
Database: {
|
||||
type: ServerConfig.DatabaseType.sqlite,
|
||||
dbFolder: 'db',
|
||||
mysql: {
|
||||
host: '',
|
||||
username: '',
|
||||
password: '',
|
||||
database: ''
|
||||
|
||||
}
|
||||
},
|
||||
Sharing: {
|
||||
updateTimeout: 1000 * 60 * 5
|
||||
},
|
||||
Threading: {
|
||||
enabled: true,
|
||||
thumbnailThreads: 0
|
||||
},
|
||||
Indexing: {
|
||||
folderPreviewSize: 2,
|
||||
cachedFolderTimeout: 1000 * 60 * 60,
|
||||
reIndexingSensitivity: ServerConfig.ReIndexingSensitivity.low,
|
||||
excludeFolderList: [],
|
||||
excludeFileList: []
|
||||
},
|
||||
Duplicates: {
|
||||
listingLimit: 1000
|
||||
},
|
||||
Jobs: {
|
||||
maxSavedProgress: 10,
|
||||
scheduled: [
|
||||
{
|
||||
name: DefaultsJobs[DefaultsJobs.Indexing],
|
||||
jobName: DefaultsJobs[DefaultsJobs.Indexing],
|
||||
allowParallelRun: false,
|
||||
config: {},
|
||||
trigger: {type: JobTriggerType.never}
|
||||
},
|
||||
{
|
||||
name: DefaultsJobs[DefaultsJobs['Thumbnail Generation']],
|
||||
jobName: DefaultsJobs[DefaultsJobs['Thumbnail Generation']],
|
||||
config: {sizes: [240]},
|
||||
allowParallelRun: false,
|
||||
trigger: {
|
||||
type: JobTriggerType.after,
|
||||
afterScheduleName: DefaultsJobs[DefaultsJobs.Indexing]
|
||||
}
|
||||
},
|
||||
/* {
|
||||
name: DefaultsJobs[DefaultsJobs['Photo Converting']],
|
||||
jobName: DefaultsJobs[DefaultsJobs['Photo Converting']],
|
||||
config: {},
|
||||
parallelRunEnabled:false,
|
||||
trigger: {
|
||||
type: JobTriggerType.after,
|
||||
afterScheduleName: DefaultsJobs[DefaultsJobs['Thumbnail Generation']]
|
||||
}
|
||||
},*/
|
||||
{
|
||||
name: DefaultsJobs[DefaultsJobs['Video Converting']],
|
||||
jobName: DefaultsJobs[DefaultsJobs['Video Converting']],
|
||||
config: {},
|
||||
allowParallelRun: false,
|
||||
trigger: {
|
||||
type: JobTriggerType.after,
|
||||
afterScheduleName: DefaultsJobs[DefaultsJobs['Thumbnail Generation']]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: DefaultsJobs[DefaultsJobs['Temp Folder Cleaning']],
|
||||
jobName: DefaultsJobs[DefaultsJobs['Temp Folder Cleaning']],
|
||||
config: {},
|
||||
allowParallelRun: false,
|
||||
trigger: {
|
||||
type: JobTriggerType.after,
|
||||
afterScheduleName: DefaultsJobs[DefaultsJobs['Video Converting']]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
20
src/common/config/private/WebConfig.ts
Normal file
20
src/common/config/private/WebConfig.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/* tslint:disable:no-inferrable-types */
|
||||
import 'reflect-metadata';
|
||||
import {ClientConfig} from '../public/ClientConfig';
|
||||
import {ServerConfig} from './PrivateConfig';
|
||||
import {WebConfigClass} from 'typeconfig/src/decorators/class/WebConfigClass';
|
||||
import {ConfigProperty} from 'typeconfig/src/decorators/property/ConfigPropoerty';
|
||||
import {ConfigDefaults} from 'typeconfig/src/decorators/property/ConfigDefaults';
|
||||
|
||||
|
||||
@WebConfigClass()
|
||||
export class WebConfig {
|
||||
@ConfigDefaults()
|
||||
Defaults: WebConfig;
|
||||
|
||||
@ConfigProperty()
|
||||
Server: ServerConfig.Config = new ServerConfig.Config();
|
||||
@ConfigProperty()
|
||||
Client: ClientConfig.Config = new ClientConfig.Config();
|
||||
|
||||
}
|
198
src/common/config/public/ClientConfig.ts
Normal file
198
src/common/config/public/ClientConfig.ts
Normal file
@ -0,0 +1,198 @@
|
||||
/* tslint:disable:no-inferrable-types */
|
||||
import 'reflect-metadata';
|
||||
import {SortingMethods} from '../../entities/SortingMethods';
|
||||
import {UserRoles} from '../../entities/UserDTO';
|
||||
import { SubConfigClass } from 'typeconfig/src/decorators/class/SubConfigClass';
|
||||
import { ConfigProperty } from 'typeconfig/src/decorators/property/ConfigPropoerty';
|
||||
|
||||
|
||||
export module ClientConfig {
|
||||
|
||||
export enum MapProviders {
|
||||
OpenStreetMap = 0, Mapbox = 1, Custom = 2
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class AutoCompleteConfig {
|
||||
@ConfigProperty()
|
||||
enabled = true;
|
||||
@ConfigProperty()
|
||||
maxItemsPerCategory = 5;
|
||||
@ConfigProperty()
|
||||
cacheTimeout: number = 1000 * 60 * 60;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class SearchConfig {
|
||||
@ConfigProperty()
|
||||
enabled: boolean = true;
|
||||
@ConfigProperty()
|
||||
instantSearchEnabled: boolean = true;
|
||||
@ConfigProperty()
|
||||
InstantSearchTimeout: number = 3000;
|
||||
@ConfigProperty()
|
||||
instantSearchCacheTimeout: number = 1000 * 60 * 60;
|
||||
@ConfigProperty()
|
||||
searchCacheTimeout: number = 1000 * 60 * 60;
|
||||
@ConfigProperty()
|
||||
AutoComplete: AutoCompleteConfig = new AutoCompleteConfig();
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class SharingConfig {
|
||||
@ConfigProperty()
|
||||
enabled: boolean = true;
|
||||
@ConfigProperty()
|
||||
passwordProtected: boolean = true;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class RandomPhotoConfig {
|
||||
@ConfigProperty()
|
||||
enabled: boolean = true;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class MapLayers {
|
||||
@ConfigProperty()
|
||||
name: string = 'street';
|
||||
@ConfigProperty()
|
||||
url: string = '';
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class MapConfig {
|
||||
@ConfigProperty()
|
||||
enabled: boolean = true;
|
||||
@ConfigProperty()
|
||||
useImageMarkers: boolean = true;
|
||||
@ConfigProperty()
|
||||
mapProvider: MapProviders = MapProviders.OpenStreetMap;
|
||||
@ConfigProperty()
|
||||
mapboxAccessToken: string = '';
|
||||
@ConfigProperty({arrayType: MapLayers})
|
||||
customLayers: MapLayers[] = [new MapLayers()];
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class ThumbnailConfig {
|
||||
@ConfigProperty()
|
||||
iconSize: number = 45;
|
||||
@ConfigProperty()
|
||||
personThumbnailSize: number = 200;
|
||||
@ConfigProperty({arrayType: Number})
|
||||
thumbnailSizes: number[] = [240, 480];
|
||||
@ConfigProperty({volatile: true})
|
||||
concurrentThumbnailGenerations: number = 1;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class NavBarConfig {
|
||||
@ConfigProperty()
|
||||
showItemCount: boolean = true;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class OtherConfig {
|
||||
@ConfigProperty()
|
||||
enableCache: boolean = true;
|
||||
@ConfigProperty()
|
||||
enableOnScrollRendering: boolean = true;
|
||||
@ConfigProperty({type: SortingMethods})
|
||||
defaultPhotoSortingMethod: SortingMethods = SortingMethods.ascDate;
|
||||
@ConfigProperty()
|
||||
enableOnScrollThumbnailPrioritising: boolean = true;
|
||||
@ConfigProperty()
|
||||
NavBar: NavBarConfig = new NavBarConfig();
|
||||
@ConfigProperty()
|
||||
captionFirstNaming: boolean = false; // shows the caption instead of the filename in the photo grid
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class VideoConfig {
|
||||
@ConfigProperty()
|
||||
enabled: boolean = true;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class PhotoConvertingConfig {
|
||||
@ConfigProperty()
|
||||
enabled: boolean = true;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class PhotoConfig {
|
||||
@ConfigProperty()
|
||||
Converting: PhotoConvertingConfig = new PhotoConvertingConfig();
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class MediaConfig {
|
||||
@ConfigProperty()
|
||||
Thumbnail: ThumbnailConfig = new ThumbnailConfig();
|
||||
@ConfigProperty()
|
||||
Video: VideoConfig = new VideoConfig();
|
||||
@ConfigProperty()
|
||||
Photo: PhotoConfig = new PhotoConfig();
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class MetaFileConfig {
|
||||
@ConfigProperty()
|
||||
enabled: boolean = true;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class FacesConfig {
|
||||
@ConfigProperty()
|
||||
enabled: boolean = true;
|
||||
@ConfigProperty()
|
||||
keywordsToPersons: boolean = true;
|
||||
@ConfigProperty({type: UserRoles})
|
||||
writeAccessMinRole: UserRoles = UserRoles.Admin;
|
||||
}
|
||||
|
||||
@SubConfigClass()
|
||||
export class Config {
|
||||
|
||||
|
||||
@ConfigProperty({volatile: true})
|
||||
upTime: string;
|
||||
@ConfigProperty({volatile: true})
|
||||
appVersion: string;
|
||||
@ConfigProperty({volatile: true})
|
||||
buildTime: string;
|
||||
@ConfigProperty({volatile: true})
|
||||
buildCommitHash: string;
|
||||
@ConfigProperty()
|
||||
applicationTitle: string = 'PiGallery 2';
|
||||
@ConfigProperty()
|
||||
publicUrl: string = '';
|
||||
@ConfigProperty()
|
||||
urlBase: string = '';
|
||||
@ConfigProperty()
|
||||
Search: SearchConfig = new SearchConfig();
|
||||
@ConfigProperty()
|
||||
Sharing: SharingConfig = new SharingConfig();
|
||||
@ConfigProperty()
|
||||
Map: MapConfig = new MapConfig();
|
||||
@ConfigProperty()
|
||||
RandomPhoto: RandomPhotoConfig = new RandomPhotoConfig();
|
||||
@ConfigProperty()
|
||||
Other: OtherConfig = new OtherConfig();
|
||||
@ConfigProperty()
|
||||
authenticationRequired: boolean = true;
|
||||
@ConfigProperty({type: UserRoles})
|
||||
unAuthenticatedUserRole: UserRoles = UserRoles.Admin;
|
||||
@ConfigProperty({arrayType: String, volatile: true})
|
||||
languages: string[];
|
||||
@ConfigProperty()
|
||||
Media: MediaConfig = new MediaConfig();
|
||||
@ConfigProperty()
|
||||
MetaFile: MetaFileConfig = new MetaFileConfig();
|
||||
@ConfigProperty()
|
||||
Faces: FacesConfig = new FacesConfig();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,16 +1,28 @@
|
||||
import {PublicConfigClass} from './ConfigClass';
|
||||
import {WebConfigLoader} from 'typeconfig/src/WebConfigLoader';
|
||||
import {ClientConfig} from './ClientConfig';
|
||||
import {WebConfigClass} from 'typeconfig/src/decorators/class/WebConfigClass';
|
||||
import {WebConfigClassBuilder} from 'typeconfig/src/decorators/builders/WebConfigClassBuilder';
|
||||
import {ConfigProperty} from 'typeconfig/src/decorators/property/ConfigPropoerty';
|
||||
|
||||
|
||||
declare module ServerInject {
|
||||
export const ConfigInject: PublicConfigClass;
|
||||
/**
|
||||
* These configuration will be available at frontend and backend too
|
||||
*/
|
||||
@WebConfigClass()
|
||||
export class ClientClass {
|
||||
|
||||
@ConfigProperty()
|
||||
public Client: ClientConfig.Config = new ClientConfig.Config();
|
||||
}
|
||||
|
||||
export let Config = new PublicConfigClass();
|
||||
declare module ServerInject {
|
||||
export const ConfigInject: ClientClass;
|
||||
}
|
||||
|
||||
export let Config = WebConfigClassBuilder.attachInterface(new ClientClass());
|
||||
|
||||
|
||||
if (typeof ServerInject !== 'undefined' && typeof ServerInject.ConfigInject !== 'undefined') {
|
||||
WebConfigLoader.loadFrontendConfig(Config.Client, ServerInject.ConfigInject);
|
||||
Config.load(ServerInject.ConfigInject);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,195 +0,0 @@
|
||||
import {SortingMethods} from '../../entities/SortingMethods';
|
||||
import {UserRoles} from '../../entities/UserDTO';
|
||||
|
||||
export module ClientConfig {
|
||||
|
||||
export enum MapProviders {
|
||||
OpenStreetMap = 0, Mapbox = 1, Custom = 2
|
||||
}
|
||||
|
||||
export interface AutoCompleteConfig {
|
||||
enabled: boolean;
|
||||
maxItemsPerCategory: number;
|
||||
cacheTimeout: number;
|
||||
}
|
||||
|
||||
export interface SearchConfig {
|
||||
enabled: boolean;
|
||||
instantSearchEnabled: boolean;
|
||||
InstantSearchTimeout: number;
|
||||
instantSearchCacheTimeout: number;
|
||||
searchCacheTimeout: number;
|
||||
AutoComplete: AutoCompleteConfig;
|
||||
}
|
||||
|
||||
export interface SharingConfig {
|
||||
enabled: boolean;
|
||||
passwordProtected: boolean;
|
||||
}
|
||||
|
||||
export interface RandomPhotoConfig {
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
export interface MapLayers {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface MapConfig {
|
||||
enabled: boolean;
|
||||
useImageMarkers: boolean;
|
||||
mapProvider: MapProviders;
|
||||
mapboxAccessToken: string;
|
||||
customLayers: MapLayers[];
|
||||
}
|
||||
|
||||
export interface ThumbnailConfig {
|
||||
iconSize: number;
|
||||
personThumbnailSize: number;
|
||||
thumbnailSizes: number[];
|
||||
concurrentThumbnailGenerations: number;
|
||||
}
|
||||
|
||||
export interface NavBarConfig {
|
||||
showItemCount: boolean;
|
||||
}
|
||||
|
||||
export interface OtherConfig {
|
||||
enableCache: boolean;
|
||||
enableOnScrollRendering: boolean;
|
||||
defaultPhotoSortingMethod: SortingMethods;
|
||||
enableOnScrollThumbnailPrioritising: boolean;
|
||||
NavBar: NavBarConfig;
|
||||
captionFirstNaming: boolean; // shows the caption instead of the filename in the photo grid
|
||||
}
|
||||
|
||||
export interface VideoConfig {
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
export interface PhotoConfig {
|
||||
Converting: {
|
||||
enabled: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface MediaConfig {
|
||||
Thumbnail: ThumbnailConfig;
|
||||
Video: VideoConfig;
|
||||
Photo: PhotoConfig;
|
||||
}
|
||||
|
||||
export interface MetaFileConfig {
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
export interface FacesConfig {
|
||||
enabled: boolean;
|
||||
keywordsToPersons: boolean;
|
||||
writeAccessMinRole: UserRoles;
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
upTime: string;
|
||||
appVersion: string;
|
||||
buildTime: string;
|
||||
buildCommitHash: string;
|
||||
applicationTitle: string;
|
||||
publicUrl: string;
|
||||
urlBase: string;
|
||||
Search: SearchConfig;
|
||||
Sharing: SharingConfig;
|
||||
Map: MapConfig;
|
||||
RandomPhoto: RandomPhotoConfig;
|
||||
Other: OtherConfig;
|
||||
authenticationRequired: boolean;
|
||||
unAuthenticatedUserRole: UserRoles;
|
||||
languages: string[];
|
||||
Media: MediaConfig;
|
||||
MetaFile: MetaFileConfig;
|
||||
Faces: FacesConfig;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* These configuration will be available at frontend and backend too
|
||||
*/
|
||||
export class PublicConfigClass {
|
||||
|
||||
public Client: ClientConfig.Config = {
|
||||
applicationTitle: 'PiGallery 2',
|
||||
appVersion: '',
|
||||
buildCommitHash: '',
|
||||
buildTime: '',
|
||||
upTime: '',
|
||||
Media: {
|
||||
Video: {
|
||||
enabled: true
|
||||
},
|
||||
Photo: {
|
||||
Converting: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
Thumbnail: {
|
||||
concurrentThumbnailGenerations: 1,
|
||||
thumbnailSizes: [240, 480],
|
||||
iconSize: 45,
|
||||
personThumbnailSize: 200
|
||||
}
|
||||
},
|
||||
Search: {
|
||||
enabled: true,
|
||||
instantSearchEnabled: true,
|
||||
InstantSearchTimeout: 3000,
|
||||
searchCacheTimeout: 1000 * 60 * 60,
|
||||
instantSearchCacheTimeout: 1000 * 60 * 60,
|
||||
AutoComplete: {
|
||||
enabled: true,
|
||||
cacheTimeout: 1000 * 60 * 60,
|
||||
maxItemsPerCategory: 5
|
||||
}
|
||||
},
|
||||
Sharing: {
|
||||
enabled: true,
|
||||
passwordProtected: true
|
||||
},
|
||||
Map: {
|
||||
enabled: true,
|
||||
useImageMarkers: true,
|
||||
mapProvider: ClientConfig.MapProviders.OpenStreetMap,
|
||||
mapboxAccessToken: '',
|
||||
customLayers: [{name: 'street', url: ''}]
|
||||
},
|
||||
RandomPhoto: {
|
||||
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
|
||||
},
|
||||
authenticationRequired: true,
|
||||
unAuthenticatedUserRole: UserRoles.Admin,
|
||||
publicUrl: '',
|
||||
urlBase: '',
|
||||
languages: []
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {ClientConfig} from '../../config/public/ConfigClass';
|
||||
import {ServerConfig} from '../../config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../config/private/PrivateConfig';
|
||||
import {ClientConfig} from '../../config/public/ClientConfig';
|
||||
|
||||
|
||||
export interface OtherConfigDTO {
|
||||
Server: ServerConfig.ThreadingConfig;
|
||||
|
@ -3,7 +3,7 @@ import {NetworkService} from '../../../model/network/network.service';
|
||||
import {FileDTO} from '../../../../../common/entities/FileDTO';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
import MapLayers = ClientConfig.MapLayers;
|
||||
|
||||
@Injectable()
|
||||
|
@ -6,10 +6,11 @@ import {ErrorDTO} from '../../../../../common/entities/Error';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {AbstractSettingsService} from './abstract.settings.service';
|
||||
import {IPrivateConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {ISettingsComponent} from './ISettingsComponent';
|
||||
import {WebConfig} from '../../../../../common/config/private/WebConfig';
|
||||
|
||||
|
||||
|
||||
export abstract class SettingsComponent<T extends { [key: string]: any }, S extends AbstractSettingsService<T> = AbstractSettingsService<T>>
|
||||
@ -44,7 +45,7 @@ export abstract class SettingsComponent<T extends { [key: string]: any }, S exte
|
||||
public _settingsService: S,
|
||||
protected notification: NotificationService,
|
||||
public i18n: I18n,
|
||||
private sliceFN?: (s: IPrivateConfig) => T) {
|
||||
private sliceFN?: (s: WebConfig) => T) {
|
||||
if (this.sliceFN) {
|
||||
this._settingsSubscription = this._settingsService.Settings.subscribe(this.onNewSettings);
|
||||
this.onNewSettings(this._settingsService._settingsService.settings.value);
|
||||
@ -68,7 +69,7 @@ export abstract class SettingsComponent<T extends { [key: string]: any }, S exte
|
||||
return this.hasAvailableSettings;
|
||||
}
|
||||
|
||||
onNewSettings = (s: IPrivateConfig) => {
|
||||
onNewSettings = (s: WebConfig) => {
|
||||
this.settings = Utils.clone(this.sliceFN(s));
|
||||
this.original = Utils.clone(this.settings);
|
||||
this.ngOnChanges();
|
||||
|
@ -6,7 +6,7 @@ import {NavigationService} from '../../../model/navigation.service';
|
||||
import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {DatabaseSettingsService} from './database.settings.service';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-database',
|
||||
|
@ -2,7 +2,7 @@ import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
@Injectable()
|
||||
export class DatabaseSettingsService extends AbstractSettingsService<ServerConfig.DataBaseConfig> {
|
||||
|
@ -3,11 +3,11 @@ import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {FacesSettingsService} from './faces.settings.service';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {UserRoles} from '../../../../../common/entities/UserDTO';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-faces',
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
@Injectable()
|
||||
export class FacesSettingsService extends AbstractSettingsService<ClientConfig.FacesConfig> {
|
||||
|
@ -9,8 +9,8 @@ import {Utils} from '../../../../../common/Utils';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
import {DefaultsJobs, JobDTO} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {JobProgressStates} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-indexing',
|
||||
|
@ -6,8 +6,8 @@ import {BehaviorSubject} from 'rxjs';
|
||||
import {StatisticDTO} from '../../../../../common/entities/settings/StatisticDTO';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
import {DefaultsJobs} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {first} from 'rxjs/operators';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
@Injectable()
|
||||
export class IndexingSettingsService extends AbstractSettingsService<ServerConfig.IndexingConfig> {
|
||||
|
@ -14,11 +14,11 @@ import {
|
||||
PeriodicJobTrigger,
|
||||
ScheduledJobTrigger
|
||||
} from '../../../../../common/entities/job/JobScheduleDTO';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ConfigTemplateEntry} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ModalDirective} from 'ngx-bootstrap/modal';
|
||||
import {JobProgressDTO, JobProgressStates} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
import {BackendtextService} from '../../../model/backendtext.service';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-jobs',
|
||||
|
@ -4,7 +4,7 @@ import {SettingsService} from '../settings.service';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
import {JobDTO} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
@Injectable()
|
||||
export class JobsSettingsService extends AbstractSettingsService<ServerConfig.JobConfig> {
|
||||
|
@ -4,9 +4,9 @@ import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Injectable()
|
||||
export class MapSettingsService extends AbstractSettingsService<ClientConfig.MapConfig> {
|
||||
|
@ -4,8 +4,8 @@ import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Injectable()
|
||||
export class MetaFileSettingsService extends AbstractSettingsService<ClientConfig.MetaFileConfig> {
|
||||
|
@ -4,13 +4,13 @@ import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {DefaultsJobs, JobDTO} from '../../../../../common/entities/job/JobDTO';
|
||||
import {JobProgressStates} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Injectable()
|
||||
export class PhotoSettingsService extends AbstractSettingsService<{
|
||||
|
@ -3,9 +3,9 @@ import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {RandomPhotoSettingsService} from './random-photo.settings.service';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-random-photo',
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Injectable()
|
||||
export class RandomPhotoSettingsService extends AbstractSettingsService<ClientConfig.SharingConfig> {
|
||||
|
@ -3,9 +3,9 @@ import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {SearchSettingsService} from './search.settings.service';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-search',
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Injectable()
|
||||
export class SearchSettingsService extends AbstractSettingsService<ClientConfig.SearchConfig> {
|
||||
|
@ -1,16 +1,17 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {IPrivateConfig} from '../../../../common/config/private/IPrivateConfig';
|
||||
import {PrivateConfigDefaultsClass} from '../../../../common/config/private/PrivateConfigDefaultsClass';
|
||||
|
||||
import {WebConfig} from '../../../../common/config/private/WebConfig';
|
||||
import {WebConfigClassBuilder} from 'typeconfig/src/decorators/builders/WebConfigClassBuilder';
|
||||
|
||||
@Injectable()
|
||||
export class SettingsService {
|
||||
public settings: BehaviorSubject<IPrivateConfig>;
|
||||
public settings: BehaviorSubject<WebConfig>;
|
||||
private fetchingSettings = false;
|
||||
|
||||
constructor(private _networkService: NetworkService) {
|
||||
this.settings = new BehaviorSubject<IPrivateConfig>(new PrivateConfigDefaultsClass());
|
||||
this.settings = new BehaviorSubject<WebConfig>(new WebConfig());
|
||||
}
|
||||
|
||||
public async getSettings(): Promise<void> {
|
||||
@ -19,7 +20,9 @@ export class SettingsService {
|
||||
}
|
||||
this.fetchingSettings = true;
|
||||
try {
|
||||
this.settings.next(await this._networkService.getJson<Promise<IPrivateConfig>>('/settings'));
|
||||
const wcg = WebConfigClassBuilder.attachInterface(new WebConfig());
|
||||
wcg.load(await this._networkService.getJson<Promise<WebConfig>>('/settings'));
|
||||
this.settings.next(wcg);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
@ -3,9 +3,9 @@ import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {ShareSettingsService} from './share.settings.service';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-share',
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
@Injectable()
|
||||
export class ShareSettingsService extends AbstractSettingsService<ClientConfig.SharingConfig> {
|
||||
|
@ -3,13 +3,13 @@ import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {ThumbnailSettingsService} from './thumbnail.settings.service';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {DefaultsJobs, JobDTO} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
import {JobProgressStates} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-thumbnail',
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Injectable()
|
||||
export class ThumbnailSettingsService
|
||||
|
@ -1,7 +1,9 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {UserDTO} from '../../../../../common/entities/UserDTO';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {IPrivateConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
|
||||
import {WebConfig} from '../../../../../common/config/private/WebConfig';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class UserManagerSettingsService {
|
||||
@ -15,7 +17,7 @@ export class UserManagerSettingsService {
|
||||
}
|
||||
|
||||
public async getSettings(): Promise<boolean> {
|
||||
return (await this._networkService.getJson<Promise<IPrivateConfig>>('/settings')).Client.authenticationRequired;
|
||||
return (await this._networkService.getJson<Promise<WebConfig>>('/settings')).Client.authenticationRequired;
|
||||
}
|
||||
|
||||
public updateSettings(settings: boolean): Promise<void> {
|
||||
|
@ -4,12 +4,12 @@ import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
import {DefaultsJobs, JobDTO} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {JobProgressStates} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||
import {SettingsService} from '../settings.service';
|
||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
import {ServerConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
|
||||
@Injectable()
|
||||
export class VideoSettingsService extends AbstractSettingsService<{ server: ServerConfig.VideoConfig, client: ClientConfig.VideoConfig }> {
|
||||
|
@ -3,7 +3,7 @@ import * as path from 'path';
|
||||
import * as util from 'util';
|
||||
import * as rimraf from 'rimraf';
|
||||
import {SQLConnection} from '../../src/backend/model/database/sql/SQLConnection';
|
||||
import {ServerConfig} from '../../src/common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../src/common/config/private/PrivateConfig';
|
||||
|
||||
declare let describe: any;
|
||||
const savedDescribe = describe;
|
||||
|
@ -17,7 +17,7 @@ import {
|
||||
} from '../../../../../src/backend/model/database/sql/enitites/PhotoEntity';
|
||||
import {MediaDimensionEntity} from '../../../../../src/backend/model/database/sql/enitites/MediaEntity';
|
||||
import {VersionEntity} from '../../../../../src/backend/model/database/sql/enitites/VersionEntity';
|
||||
import {ServerConfig} from '../../../../../src/common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../../src/common/config/private/PrivateConfig';
|
||||
|
||||
|
||||
const rimrafPR = util.promisify(rimraf);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {Config} from '../../../../src/common/config/private/Config';
|
||||
import {ServerConfig} from '../../../../src/common/config/private/IPrivateConfig';
|
||||
import {Server} from '../../../../src/backend/server';
|
||||
import * as path from 'path';
|
||||
import * as util from 'util';
|
||||
@ -8,6 +7,7 @@ import * as rimraf from 'rimraf';
|
||||
import {SQLConnection} from '../../../../src/backend/model/database/sql/SQLConnection';
|
||||
import {SuperAgentStatic} from 'superagent';
|
||||
import {ProjectPath} from '../../../../src/backend/ProjectPath';
|
||||
import {ServerConfig} from '../../../../src/common/config/private/PrivateConfig';
|
||||
|
||||
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {Config} from '../../../../src/common/config/private/Config';
|
||||
import {ServerConfig} from '../../../../src/common/config/private/IPrivateConfig';
|
||||
import {Server} from '../../../../src/backend/server';
|
||||
import {LoginCredential} from '../../../../src/common/entities/LoginCredential';
|
||||
import {UserDTO, UserRoles} from '../../../../src/common/entities/UserDTO';
|
||||
@ -13,6 +12,7 @@ import {SuperAgentStatic} from 'superagent';
|
||||
import {RouteTestingHelper} from './RouteTestingHelper';
|
||||
import {QueryParams} from '../../../../src/common/QueryParams';
|
||||
import {ErrorCodes} from '../../../../src/common/entities/Error';
|
||||
import {ServerConfig} from '../../../../src/common/config/private/PrivateConfig';
|
||||
|
||||
|
||||
process.env.NODE_ENV = 'test';
|
||||
@ -109,7 +109,7 @@ describe('SharingRouter', () => {
|
||||
});
|
||||
|
||||
it('should login with no-password share', async () => {
|
||||
const sharing = await RouteTestingHelper.createSharing(testUser,);
|
||||
const sharing = await RouteTestingHelper.createSharing(testUser);
|
||||
const res = await shareLogin(server, sharing.sharingKey, sharing.password);
|
||||
shouldBeValidUser(res, RouteTestingHelper.getExpectedSharingUser(sharing));
|
||||
});
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {Config} from '../../../../src/common/config/private/Config';
|
||||
import {ServerConfig} from '../../../../src/common/config/private/IPrivateConfig';
|
||||
import {Server} from '../../../../src/backend/server';
|
||||
import {LoginCredential} from '../../../../src/common/entities/LoginCredential';
|
||||
import {UserDTO, UserRoles} from '../../../../src/common/entities/UserDTO';
|
||||
@ -13,6 +12,7 @@ import {Utils} from '../../../../src/common/Utils';
|
||||
import {SuperAgentStatic} from 'superagent';
|
||||
import {RouteTestingHelper} from './RouteTestingHelper';
|
||||
import {ErrorCodes} from '../../../../src/common/entities/Error';
|
||||
import {ServerConfig} from '../../../../src/common/config/private/PrivateConfig';
|
||||
|
||||
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
@ -2,9 +2,9 @@ import * as path from 'path';
|
||||
import * as util from 'util';
|
||||
import * as rimraf from 'rimraf';
|
||||
import {Config} from '../../../../../src/common/config/private/Config';
|
||||
import {ServerConfig} from '../../../../../src/common/config/private/IPrivateConfig';
|
||||
import {SQLConnection} from '../../../../../src/backend/model/database/sql/SQLConnection';
|
||||
import {Server} from '../../../../../src/backend/server';
|
||||
import {ServerConfig} from '../../../../../src/common/config/private/PrivateConfig';
|
||||
|
||||
process.env.NODE_ENV = 'test';
|
||||
const chai: any = require('chai');
|
||||
@ -32,7 +32,7 @@ describe('SettingsRouter', () => {
|
||||
describe('/GET settings', () => {
|
||||
it('it should GET all the books', async () => {
|
||||
Config.Client.authenticationRequired = false;
|
||||
const originalSettings = Config.original();
|
||||
const originalSettings = await Config.original();
|
||||
originalSettings.Server.sessionSecret = null;
|
||||
const srv = new Server();
|
||||
await srv.onStarted.wait();
|
||||
|
@ -16,7 +16,7 @@ import {PersonManager} from '../../../../../src/backend/model/database/sql/Perso
|
||||
import {SQLTestHelper} from '../../../SQLTestHelper';
|
||||
import {VersionManager} from '../../../../../src/backend/model/database/sql/VersionManager';
|
||||
import {DiskMangerWorker} from '../../../../../src/backend/model/threading/DiskMangerWorker';
|
||||
import {ServerConfig} from '../../../../../src/common/config/private/IPrivateConfig';
|
||||
import {ServerConfig} from '../../../../../src/common/config/private/PrivateConfig';
|
||||
|
||||
class GalleryManagerTest extends GalleryManager {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user