improving settings
This commit is contained in:
parent
a80297ce0c
commit
5311df68e5
@ -301,6 +301,43 @@ export class SettingsMWs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async updatePhotoSettings(req: Request, res: Response, next: NextFunction) {
|
||||||
|
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||||
|
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const settings: {
|
||||||
|
photoProcessingLibrary: ServerConfig.PhotoProcessingLib,
|
||||||
|
server: ServerConfig.PhotoConfig,
|
||||||
|
client: ClientConfig.PhotoConfig
|
||||||
|
} = req.body.settings;
|
||||||
|
|
||||||
|
await ConfigDiagnostics.testThumbnailLib(settings.photoProcessingLibrary);
|
||||||
|
await ConfigDiagnostics.testServerPhotoConfig(settings.server);
|
||||||
|
await ConfigDiagnostics.testClientPhotoConfig(settings.client);
|
||||||
|
Config.Server.Media.photoProcessingLibrary = settings.photoProcessingLibrary;
|
||||||
|
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();
|
||||||
|
original.Server.Media.photoProcessingLibrary = settings.photoProcessingLibrary;
|
||||||
|
original.Server.Media.Photo = settings.server;
|
||||||
|
original.Client.Media.Photo = settings.client;
|
||||||
|
original.save();
|
||||||
|
ProjectPath.reset();
|
||||||
|
await ConfigDiagnostics.runDiagnostics();
|
||||||
|
Logger.info(LOG_TAG, 'new config:');
|
||||||
|
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||||
|
return next();
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof Error) {
|
||||||
|
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + err.toString(), err));
|
||||||
|
}
|
||||||
|
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static async updateBasicSettings(req: Request, res: Response, next: NextFunction) {
|
public static async updateBasicSettings(req: Request, res: Response, next: NextFunction) {
|
||||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||||
|
|||||||
@ -120,6 +120,15 @@ export class ConfigDiagnostics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static async testServerPhotoConfig(server: ServerConfig.PhotoConfig) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static async testClientPhotoConfig(client: ClientConfig.PhotoConfig) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static async testServerThumbnailConfig(server: ServerConfig.ThumbnailConfig) {
|
public static async testServerThumbnailConfig(server: ServerConfig.ThumbnailConfig) {
|
||||||
if (server.personFaceMargin < 0 || server.personFaceMargin > 1) {
|
if (server.personFaceMargin < 0 || server.personFaceMargin > 1) {
|
||||||
throw new Error('personFaceMargin should be between 0 and 1');
|
throw new Error('personFaceMargin should be between 0 and 1');
|
||||||
@ -142,7 +151,7 @@ export class ConfigDiagnostics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static async testTasksConfig(faces: ServerConfig.TaskConfig, config: IPrivateConfig) {
|
static async testTasksConfig(task: ServerConfig.TaskConfig, config: IPrivateConfig) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,12 @@ export class SettingsRouter {
|
|||||||
SettingsMWs.updateVideoSettings,
|
SettingsMWs.updateVideoSettings,
|
||||||
RenderingMWs.renderOK
|
RenderingMWs.renderOK
|
||||||
);
|
);
|
||||||
|
app.put('/api/settings/photo',
|
||||||
|
AuthenticationMWs.authenticate,
|
||||||
|
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||||
|
SettingsMWs.updatePhotoSettings,
|
||||||
|
RenderingMWs.renderOK
|
||||||
|
);
|
||||||
app.put('/api/settings/metafile',
|
app.put('/api/settings/metafile',
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||||
|
|||||||
@ -17,6 +17,10 @@ export class MetaFileSettingsService extends AbstractSettingsService<ClientConfi
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
showInSimplifiedMode(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public updateSettings(settings: ClientConfig.MetaFileConfig): Promise<void> {
|
public updateSettings(settings: ClientConfig.MetaFileConfig): Promise<void> {
|
||||||
return this._networkService.putJson('/settings/metafile', {settings: settings});
|
return this._networkService.putJson('/settings/metafile', {settings: settings});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,8 +24,7 @@
|
|||||||
<small *ngIf="settings.photoProcessingLibrary==PhotoProcessingLib.gm"
|
<small *ngIf="settings.photoProcessingLibrary==PhotoProcessingLib.gm"
|
||||||
class="form-text text-muted">
|
class="form-text text-muted">
|
||||||
<ng-container i18n>Make sure that gm node module and</ng-container>
|
<ng-container i18n>Make sure that gm node module and</ng-container>
|
||||||
<a
|
<a href="http://www.graphicsmagick.org/">GraphicsMagick</a>
|
||||||
href="http://www.graphicsmagick.org/" i18n>GraphicsMagick</a>
|
|
||||||
<ng-container i18n>are installed (npm install sharp).</ng-container>
|
<ng-container i18n>are installed (npm install sharp).</ng-container>
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
@ -56,7 +55,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group row" [hidden]="!settings.client.Converting.enabled">
|
<div class="form-group row" [hidden]="!settings.client.Converting.enabled || simplifiedMode">
|
||||||
<label class="col-md-2 control-label" for="onTheFlyConverting" i18n>On the fly converting </label>
|
<label class="col-md-2 control-label" for="onTheFlyConverting" i18n>On the fly converting </label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<bSwitch
|
<bSwitch
|
||||||
|
|||||||
@ -6,14 +6,22 @@ import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
|||||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PhotoSettingsService extends AbstractSettingsService<{ server: ServerConfig.PhotoConfig, client: ClientConfig.PhotoConfig }> {
|
export class PhotoSettingsService extends AbstractSettingsService<{
|
||||||
|
photoProcessingLibrary: ServerConfig.PhotoProcessingLib,
|
||||||
|
server: ServerConfig.PhotoConfig,
|
||||||
|
client: ClientConfig.PhotoConfig
|
||||||
|
}> {
|
||||||
constructor(private _networkService: NetworkService,
|
constructor(private _networkService: NetworkService,
|
||||||
_settingsService: SettingsService) {
|
_settingsService: SettingsService) {
|
||||||
super(_settingsService);
|
super(_settingsService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public updateSettings(settings: { server: ServerConfig.PhotoConfig, client: ClientConfig.PhotoConfig }): Promise<void> {
|
public updateSettings(settings: {
|
||||||
|
photoProcessingLibrary: ServerConfig.PhotoProcessingLib,
|
||||||
|
server: ServerConfig.PhotoConfig,
|
||||||
|
client: ClientConfig.PhotoConfig
|
||||||
|
}): Promise<void> {
|
||||||
return this._networkService.putJson('/settings/photo', {settings: settings});
|
return this._networkService.putJson('/settings/photo', {settings: settings});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -64,9 +64,6 @@ export class TasksSettingsComponent extends SettingsComponent<ServerConfig.TaskC
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngOnChanges(): void {
|
|
||||||
this.hasAvailableSettings = !this.simplifiedMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
getConfigTemplate(taskName: string): ConfigTemplateEntry[] {
|
getConfigTemplate(taskName: string): ConfigTemplateEntry[] {
|
||||||
const task = this._settingsService.availableTasks.value.find(t => t.Name === taskName);
|
const task = this._settingsService.availableTasks.value.find(t => t.Name === taskName);
|
||||||
|
|||||||
@ -22,6 +22,11 @@ export class TasksSettingsService extends AbstractSettingsService<ServerConfig.T
|
|||||||
return this._networkService.putJson('/settings/tasks', {settings: settings});
|
return this._networkService.putJson('/settings/tasks', {settings: settings});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
showInSimplifiedMode(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public isSupported(): boolean {
|
public isSupported(): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,62 +1,69 @@
|
|||||||
<form #settingsForm="ngForm" class="form-horizontal">
|
<form #settingsForm="ngForm" class="form-horizontal">
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<h5 class="card-header">
|
<h5 class="card-header">
|
||||||
{{Name}}<ng-container *ngIf="changed">*</ng-container>
|
{{Name}}
|
||||||
|
<ng-container *ngIf="changed">*</ng-container>
|
||||||
</h5>
|
</h5>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group row" [hidden]="simplifiedMode">
|
<div class="form-group row" [hidden]="simplifiedMode">
|
||||||
<label class="col-md-2 control-label" for="quality" i18n>Thumbnail Quality</label>
|
<label class="col-md-2 control-label" for="quality" i18n>Thumbnail Quality</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<bSwitch
|
<bSwitch
|
||||||
id="quality"
|
id="quality"
|
||||||
class="switch"
|
class="switch"
|
||||||
name="enabled"
|
name="enabled"
|
||||||
[switch-on-color]="'primary'"
|
[switch-on-color]="'primary'"
|
||||||
[switch-inverse]="true"
|
[switch-inverse]="true"
|
||||||
[switch-off-text]="text.Low"
|
[switch-off-text]="text.Low"
|
||||||
[switch-on-text]="text.High"
|
[switch-on-text]="text.High"
|
||||||
[switch-handle-width]="100"
|
[switch-handle-width]="100"
|
||||||
[switch-label-width]="20"
|
[switch-label-width]="20"
|
||||||
[(ngModel)]="settings.server.qualityPriority">
|
[(ngModel)]="settings.server.qualityPriority">
|
||||||
</bSwitch>
|
</bSwitch>
|
||||||
<small class="form-text text-muted" i18n>High quality may be slow. Especially with Jimp.</small>
|
<small class="form-text text-muted" i18n>High quality may be slow. Especially with Jimp.</small>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group row" [hidden]="simplifiedMode">
|
<div class="form-group row" [hidden]="simplifiedMode">
|
||||||
<label class="col-md-2 control-label" for="icon">Icon size</label>
|
<label class="col-md-2 control-label" for="icon">Icon size</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<input type="number" class="form-control" placeholder="30"
|
<input type="number" class="form-control" placeholder="30"
|
||||||
id="icon"
|
id="icon"
|
||||||
[(ngModel)]="settings.client.iconSize"
|
[(ngModel)]="settings.client.iconSize"
|
||||||
min="1"
|
min="1"
|
||||||
max="100"
|
max="100"
|
||||||
step="1"
|
step="1"
|
||||||
name="icon" required>
|
name="icon" required>
|
||||||
<small class="form-text text-muted" i18n>Icon size (used on maps)</small>
|
<small class="form-text text-muted" i18n>Icon size (used on maps)</small>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group row" [hidden]="simplifiedMode">
|
<div class="form-group row" [hidden]="simplifiedMode">
|
||||||
<label class="col-md-2 control-label" for="thumbnailSizes" i18n>Thumbnail sizes</label>
|
<label class="col-md-2 control-label" for="thumbnailSizes" i18n>Thumbnail sizes</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<input type="text" class="form-control" placeholder="160; 240"
|
<input type="text" class="form-control" placeholder="160; 240"
|
||||||
id="thumbnailSizes"
|
id="thumbnailSizes"
|
||||||
[(ngModel)]="ThumbnailSizes"
|
[(ngModel)]="ThumbnailSizes"
|
||||||
name="thumbnailSizes" required>
|
name="thumbnailSizes" required>
|
||||||
<small class="form-text text-muted">
|
<small class="form-text text-muted">
|
||||||
<ng-container i18n>Size of the thumbnails.</ng-container><br/>
|
<ng-container i18n>Size of the thumbnails.</ng-container>
|
||||||
<ng-container i18n>The best matching size will be generated. (More sizes give better quality, but use more storage and CPU to render.)</ng-container><br/>
|
<br/>
|
||||||
<ng-container i18n>';' separated integers. If size is 160, that shorter side of the thumbnail will have 160 pixels.</ng-container>
|
<ng-container i18n>The best matching size will be generated. (More sizes give better quality, but use more
|
||||||
</small>
|
storage and CPU to render.)
|
||||||
|
</ng-container>
|
||||||
|
<br/>
|
||||||
|
<ng-container i18n>';' separated integers. If size is 160, that shorter side of the thumbnail will have 160
|
||||||
|
pixels.
|
||||||
|
</ng-container>
|
||||||
|
</small>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-success float-right"
|
<button class="btn btn-success float-right"
|
||||||
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
||||||
@ -66,8 +73,31 @@
|
|||||||
[disabled]=" !changed || inProgress"
|
[disabled]=" !changed || inProgress"
|
||||||
(click)="reset()" i18n>Reset
|
(click)="reset()" i18n>Reset
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
<button class="btn btn-success float-left ml-0"
|
||||||
|
*ngIf="Progress == null"
|
||||||
|
[disabled]="inProgress"
|
||||||
|
title="Indexes the folders"
|
||||||
|
i18n-title
|
||||||
|
(click)="startTask()">
|
||||||
|
<ng-container i18n>Convert photos now</ng-container>
|
||||||
|
<span class="oi oi-media-play ml-2"></span>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-secondary float-left ml-0"
|
||||||
|
*ngIf="Progress != null"
|
||||||
|
[disabled]="inProgress || Progress.state !== TaskState.running"
|
||||||
|
(click)="cancelTask()" i18n>Cancel converting
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
<ng-container *ngIf="Progress != null">
|
||||||
|
<br/>
|
||||||
|
<hr/>
|
||||||
|
<app-settings-tasks-progress [progress]="Progress"></app-settings-tasks-progress>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -5,9 +5,12 @@ import {NavigationService} from '../../../model/navigation.service';
|
|||||||
import {NotificationService} from '../../../model/notification.service';
|
import {NotificationService} from '../../../model/notification.service';
|
||||||
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
import {ClientConfig} from '../../../../../common/config/public/ConfigClass';
|
||||||
import {ThumbnailSettingsService} from './thumbnail.settings.service';
|
import {ThumbnailSettingsService} from './thumbnail.settings.service';
|
||||||
import {Utils} from '../../../../../common/Utils';
|
|
||||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||||
|
import {DefaultsTasks} from '../../../../../common/entities/task/TaskDTO';
|
||||||
|
import {ErrorDTO} from '../../../../../common/entities/Error';
|
||||||
|
import {ScheduledTasksService} from '../scheduled-tasks.service';
|
||||||
|
import {TaskState} from '../../../../../common/entities/settings/TaskProgressDTO';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-settings-thumbnail',
|
selector: 'app-settings-thumbnail',
|
||||||
@ -19,12 +22,13 @@ import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig'
|
|||||||
export class ThumbnailSettingsComponent
|
export class ThumbnailSettingsComponent
|
||||||
extends SettingsComponent<{ server: ServerConfig.ThumbnailConfig, client: ClientConfig.ThumbnailConfig }>
|
extends SettingsComponent<{ server: ServerConfig.ThumbnailConfig, client: ClientConfig.ThumbnailConfig }>
|
||||||
implements OnInit {
|
implements OnInit {
|
||||||
ThumbnailProcessingLib: any;
|
TaskState = TaskState;
|
||||||
|
|
||||||
constructor(_authService: AuthenticationService,
|
constructor(_authService: AuthenticationService,
|
||||||
_navigation: NavigationService,
|
_navigation: NavigationService,
|
||||||
_settingsService: ThumbnailSettingsService,
|
_settingsService: ThumbnailSettingsService,
|
||||||
notification: NotificationService,
|
notification: NotificationService,
|
||||||
|
public tasksService: ScheduledTasksService,
|
||||||
i18n: I18n) {
|
i18n: I18n) {
|
||||||
super(i18n('Thumbnail'), _authService, _navigation, _settingsService, notification, i18n, s => ({
|
super(i18n('Thumbnail'), _authService, _navigation, _settingsService, notification, i18n, s => ({
|
||||||
client: s.Client.Media.Thumbnail,
|
client: s.Client.Media.Thumbnail,
|
||||||
@ -44,11 +48,51 @@ export class ThumbnailSettingsComponent
|
|||||||
.filter(i => !isNaN(i) && i > 0);
|
.filter(i => !isNaN(i) && i > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get Progress() {
|
||||||
|
return this.tasksService.progress.value[DefaultsTasks[DefaultsTasks['Thumbnail Generation']]];
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async startTask() {
|
||||||
|
this.inProgress = true;
|
||||||
|
this.error = '';
|
||||||
|
try {
|
||||||
|
await this.tasksService.start(DefaultsTasks[DefaultsTasks['Thumbnail Generation']], {sizes: this.original.client.thumbnailSizes[0]});
|
||||||
|
this.notification.info(this.i18n('Thumbnail generation started'));
|
||||||
|
this.inProgress = false;
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
if (err.message) {
|
||||||
|
this.error = (<ErrorDTO>err).message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inProgress = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async cancelTask() {
|
||||||
|
this.inProgress = true;
|
||||||
|
this.error = '';
|
||||||
|
try {
|
||||||
|
await this.tasksService.stop(DefaultsTasks[DefaultsTasks['Thumbnail Generation']]);
|
||||||
|
this.notification.info(this.i18n('Thumbnail generation interrupted'));
|
||||||
|
this.inProgress = false;
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
if (err.message) {
|
||||||
|
this.error = (<ErrorDTO>err).message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inProgress = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,10 @@ export class ThumbnailSettingsService
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
showInSimplifiedMode(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public updateSettings(settings: { server: ServerConfig.ThumbnailConfig, client: ClientConfig.ThumbnailConfig }): Promise<void> {
|
public updateSettings(settings: { server: ServerConfig.ThumbnailConfig, client: ClientConfig.ThumbnailConfig }): Promise<void> {
|
||||||
return this._networkService.putJson('/settings/thumbnail', {settings: settings});
|
return this._networkService.putJson('/settings/thumbnail', {settings: settings});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user