feat(server): custom library scanning interval (#4390)

* add automatic library scan config options

* add validation

* open api

* use CronJob instead of cron-validator

* fix tests

* catch potential error of the library scan initialization

* better description for input field

* move library scan job initialization to server app service

* fix tests

* add comments to all parameters of cronjob contructor

* make scan a child of a more general library object

* open api

* chore: cleanup

* move cronjob handling to job repoistory

* web: select for common cron expressions

* fix open api

* fix tests

* put scanning settings in nested accordion

* fix system config validation

* refactor, tests

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
Daniel Dietzler
2023-10-31 21:19:12 +01:00
committed by GitHub
parent 088d5addf2
commit cd375a976e
35 changed files with 786 additions and 114 deletions
@@ -1,4 +1,5 @@
export * from './system-config-ffmpeg.dto';
export * from './system-config-library.dto';
export * from './system-config-oauth.dto';
export * from './system-config-password-login.dto';
export * from './system-config-storage-template.dto';
@@ -0,0 +1,40 @@
import { validateCronExpression } from '@app/domain';
import { Type } from 'class-transformer';
import {
IsBoolean,
IsNotEmpty,
IsObject,
IsString,
Validate,
ValidateIf,
ValidateNested,
ValidatorConstraint,
ValidatorConstraintInterface,
} from 'class-validator';
const isEnabled = (config: SystemConfigLibraryScanDto) => config.enabled;
@ValidatorConstraint({ name: 'cronValidator' })
class CronValidator implements ValidatorConstraintInterface {
validate(expression: string): boolean {
return validateCronExpression(expression);
}
}
export class SystemConfigLibraryScanDto {
@IsBoolean()
enabled!: boolean;
@ValidateIf(isEnabled)
@IsNotEmpty()
@Validate(CronValidator, { message: 'Invalid cron expression' })
@IsString()
cronExpression!: string;
}
export class SystemConfigLibraryDto {
@Type(() => SystemConfigLibraryScanDto)
@ValidateNested()
@IsObject()
scan!: SystemConfigLibraryScanDto;
}
@@ -3,6 +3,7 @@ import { Type } from 'class-transformer';
import { IsObject, ValidateNested } from 'class-validator';
import { SystemConfigFFmpegDto } from './system-config-ffmpeg.dto';
import { SystemConfigJobDto } from './system-config-job.dto';
import { SystemConfigLibraryDto } from './system-config-library.dto';
import { SystemConfigMachineLearningDto } from './system-config-machine-learning.dto';
import { SystemConfigMapDto } from './system-config-map.dto';
import { SystemConfigNewVersionCheckDto } from './system-config-new-version-check.dto';
@@ -74,6 +75,11 @@ export class SystemConfigDto implements SystemConfig {
@ValidateNested()
@IsObject()
theme!: SystemConfigThemeDto;
@Type(() => SystemConfigLibraryDto)
@ValidateNested()
@IsObject()
library!: SystemConfigLibraryDto;
}
export function mapConfig(config: SystemConfig): SystemConfigDto {
@@ -13,6 +13,7 @@ import {
VideoCodec,
} from '@app/infra/entities';
import { BadRequestException, ForbiddenException, Injectable, Logger } from '@nestjs/common';
import { CronExpression } from '@nestjs/schedule';
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
import * as _ from 'lodash';
@@ -120,6 +121,12 @@ export const defaults = Object.freeze<SystemConfig>({
theme: {
customCss: '',
},
library: {
scan: {
enabled: true,
cronExpression: CronExpression.EVERY_DAY_AT_MIDNIGHT,
},
},
});
export enum FeatureFlag {
@@ -121,6 +121,12 @@ const updatedConfig = Object.freeze<SystemConfig>({
theme: {
customCss: '',
},
library: {
scan: {
enabled: true,
cronExpression: '0 0 * * *',
},
},
});
describe(SystemConfigService.name, () => {