1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00

improving settings

This commit is contained in:
Patrik J. Braun 2019-12-15 15:53:03 +01:00
parent a80297ce0c
commit 5311df68e5
11 changed files with 199 additions and 56 deletions

View File

@ -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) {
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));

View File

@ -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) {
if (server.personFaceMargin < 0 || server.personFaceMargin > 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) {
}

View File

@ -37,6 +37,12 @@ export class SettingsRouter {
SettingsMWs.updateVideoSettings,
RenderingMWs.renderOK
);
app.put('/api/settings/photo',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
SettingsMWs.updatePhotoSettings,
RenderingMWs.renderOK
);
app.put('/api/settings/metafile',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),

View File

@ -17,6 +17,10 @@ export class MetaFileSettingsService extends AbstractSettingsService<ClientConfi
}
showInSimplifiedMode(): boolean {
return false;
}
public updateSettings(settings: ClientConfig.MetaFileConfig): Promise<void> {
return this._networkService.putJson('/settings/metafile', {settings: settings});
}

View File

@ -24,8 +24,7 @@
<small *ngIf="settings.photoProcessingLibrary==PhotoProcessingLib.gm"
class="form-text text-muted">
<ng-container i18n>Make sure that gm node module and</ng-container>
<a
href="http://www.graphicsmagick.org/" i18n>GraphicsMagick</a>
<a href="http://www.graphicsmagick.org/">GraphicsMagick</a>
<ng-container i18n>are installed (npm install sharp).</ng-container>
</small>
@ -56,7 +55,7 @@
</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>
<div class="col-md-10">
<bSwitch

View File

@ -6,14 +6,22 @@ import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
@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,
_settingsService: 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});
}

View File

@ -64,9 +64,6 @@ export class TasksSettingsComponent extends SettingsComponent<ServerConfig.TaskC
}
ngOnChanges(): void {
this.hasAvailableSettings = !this.simplifiedMode;
}
getConfigTemplate(taskName: string): ConfigTemplateEntry[] {
const task = this._settingsService.availableTasks.value.find(t => t.Name === taskName);

View File

@ -22,6 +22,11 @@ export class TasksSettingsService extends AbstractSettingsService<ServerConfig.T
return this._networkService.putJson('/settings/tasks', {settings: settings});
}
showInSimplifiedMode(): boolean {
return false;
}
public isSupported(): boolean {
return true;
}

View File

@ -1,62 +1,69 @@
<form #settingsForm="ngForm" class="form-horizontal">
<div class="card mb-4">
<h5 class="card-header">
{{Name}}<ng-container *ngIf="changed">*</ng-container>
{{Name}}
<ng-container *ngIf="changed">*</ng-container>
</h5>
<div class="card-body">
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
<div class="form-group row" [hidden]="simplifiedMode">
<label class="col-md-2 control-label" for="quality" i18n>Thumbnail Quality</label>
<div class="col-md-10">
<bSwitch
id="quality"
class="switch"
name="enabled"
[switch-on-color]="'primary'"
[switch-inverse]="true"
[switch-off-text]="text.Low"
[switch-on-text]="text.High"
[switch-handle-width]="100"
[switch-label-width]="20"
[(ngModel)]="settings.server.qualityPriority">
</bSwitch>
<small class="form-text text-muted" i18n>High quality may be slow. Especially with Jimp.</small>
<div class="form-group row" [hidden]="simplifiedMode">
<label class="col-md-2 control-label" for="quality" i18n>Thumbnail Quality</label>
<div class="col-md-10">
<bSwitch
id="quality"
class="switch"
name="enabled"
[switch-on-color]="'primary'"
[switch-inverse]="true"
[switch-off-text]="text.Low"
[switch-on-text]="text.High"
[switch-handle-width]="100"
[switch-label-width]="20"
[(ngModel)]="settings.server.qualityPriority">
</bSwitch>
<small class="form-text text-muted" i18n>High quality may be slow. Especially with Jimp.</small>
</div>
</div>
</div>
<div class="form-group row" [hidden]="simplifiedMode">
<label class="col-md-2 control-label" for="icon">Icon size</label>
<div class="col-md-10">
<input type="number" class="form-control" placeholder="30"
id="icon"
[(ngModel)]="settings.client.iconSize"
min="1"
max="100"
step="1"
name="icon" required>
<small class="form-text text-muted" i18n>Icon size (used on maps)</small>
<div class="form-group row" [hidden]="simplifiedMode">
<label class="col-md-2 control-label" for="icon">Icon size</label>
<div class="col-md-10">
<input type="number" class="form-control" placeholder="30"
id="icon"
[(ngModel)]="settings.client.iconSize"
min="1"
max="100"
step="1"
name="icon" required>
<small class="form-text text-muted" i18n>Icon size (used on maps)</small>
</div>
</div>
</div>
<div class="form-group row" [hidden]="simplifiedMode">
<label class="col-md-2 control-label" for="thumbnailSizes" i18n>Thumbnail sizes</label>
<div class="col-md-10">
<input type="text" class="form-control" placeholder="160; 240"
id="thumbnailSizes"
[(ngModel)]="ThumbnailSizes"
name="thumbnailSizes" required>
<small class="form-text text-muted">
<ng-container i18n>Size of the thumbnails.</ng-container><br/>
<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/>
<ng-container i18n>';' separated integers. If size is 160, that shorter side of the thumbnail will have 160 pixels.</ng-container>
</small>
<div class="form-group row" [hidden]="simplifiedMode">
<label class="col-md-2 control-label" for="thumbnailSizes" i18n>Thumbnail sizes</label>
<div class="col-md-10">
<input type="text" class="form-control" placeholder="160; 240"
id="thumbnailSizes"
[(ngModel)]="ThumbnailSizes"
name="thumbnailSizes" required>
<small class="form-text text-muted">
<ng-container i18n>Size of the thumbnails.</ng-container>
<br/>
<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/>
<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>
<button class="btn btn-success float-right"
[disabled]="!settingsForm.form.valid || !changed || inProgress"
@ -66,8 +73,31 @@
[disabled]=" !changed || inProgress"
(click)="reset()" i18n>Reset
</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>
</form>

View File

@ -5,9 +5,12 @@ 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 {Utils} from '../../../../../common/Utils';
import {I18n} from '@ngx-translate/i18n-polyfill';
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({
selector: 'app-settings-thumbnail',
@ -19,12 +22,13 @@ import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig'
export class ThumbnailSettingsComponent
extends SettingsComponent<{ server: ServerConfig.ThumbnailConfig, client: ClientConfig.ThumbnailConfig }>
implements OnInit {
ThumbnailProcessingLib: any;
TaskState = TaskState;
constructor(_authService: AuthenticationService,
_navigation: NavigationService,
_settingsService: ThumbnailSettingsService,
notification: NotificationService,
public tasksService: ScheduledTasksService,
i18n: I18n) {
super(i18n('Thumbnail'), _authService, _navigation, _settingsService, notification, i18n, s => ({
client: s.Client.Media.Thumbnail,
@ -44,11 +48,51 @@ export class ThumbnailSettingsComponent
.filter(i => !isNaN(i) && i > 0);
}
get Progress() {
return this.tasksService.progress.value[DefaultsTasks[DefaultsTasks['Thumbnail Generation']]];
}
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;
}
}

View File

@ -14,6 +14,10 @@ export class ThumbnailSettingsService
}
showInSimplifiedMode(): boolean {
return false;
}
public updateSettings(settings: { server: ServerConfig.ThumbnailConfig, client: ClientConfig.ThumbnailConfig }): Promise<void> {
return this._networkService.putJson('/settings/thumbnail', {settings: settings});
}