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
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 786 additions and 114 deletions

View file

@ -15,6 +15,7 @@ class SystemConfigDto {
SystemConfigDto({
required this.ffmpeg,
required this.job,
required this.library_,
required this.machineLearning,
required this.map,
required this.newVersionCheck,
@ -31,6 +32,8 @@ class SystemConfigDto {
SystemConfigJobDto job;
SystemConfigLibraryDto library_;
SystemConfigMachineLearningDto machineLearning;
SystemConfigMapDto map;
@ -55,6 +58,7 @@ class SystemConfigDto {
bool operator ==(Object other) => identical(this, other) || other is SystemConfigDto &&
other.ffmpeg == ffmpeg &&
other.job == job &&
other.library_ == library_ &&
other.machineLearning == machineLearning &&
other.map == map &&
other.newVersionCheck == newVersionCheck &&
@ -71,6 +75,7 @@ class SystemConfigDto {
// ignore: unnecessary_parenthesis
(ffmpeg.hashCode) +
(job.hashCode) +
(library_.hashCode) +
(machineLearning.hashCode) +
(map.hashCode) +
(newVersionCheck.hashCode) +
@ -83,12 +88,13 @@ class SystemConfigDto {
(trash.hashCode);
@override
String toString() => 'SystemConfigDto[ffmpeg=$ffmpeg, job=$job, machineLearning=$machineLearning, map=$map, newVersionCheck=$newVersionCheck, oauth=$oauth, passwordLogin=$passwordLogin, reverseGeocoding=$reverseGeocoding, storageTemplate=$storageTemplate, theme=$theme, thumbnail=$thumbnail, trash=$trash]';
String toString() => 'SystemConfigDto[ffmpeg=$ffmpeg, job=$job, library_=$library_, machineLearning=$machineLearning, map=$map, newVersionCheck=$newVersionCheck, oauth=$oauth, passwordLogin=$passwordLogin, reverseGeocoding=$reverseGeocoding, storageTemplate=$storageTemplate, theme=$theme, thumbnail=$thumbnail, trash=$trash]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
json[r'ffmpeg'] = this.ffmpeg;
json[r'job'] = this.job;
json[r'library'] = this.library_;
json[r'machineLearning'] = this.machineLearning;
json[r'map'] = this.map;
json[r'newVersionCheck'] = this.newVersionCheck;
@ -112,6 +118,7 @@ class SystemConfigDto {
return SystemConfigDto(
ffmpeg: SystemConfigFFmpegDto.fromJson(json[r'ffmpeg'])!,
job: SystemConfigJobDto.fromJson(json[r'job'])!,
library_: SystemConfigLibraryDto.fromJson(json[r'library'])!,
machineLearning: SystemConfigMachineLearningDto.fromJson(json[r'machineLearning'])!,
map: SystemConfigMapDto.fromJson(json[r'map'])!,
newVersionCheck: SystemConfigNewVersionCheckDto.fromJson(json[r'newVersionCheck'])!,
@ -171,6 +178,7 @@ class SystemConfigDto {
static const requiredKeys = <String>{
'ffmpeg',
'job',
'library',
'machineLearning',
'map',
'newVersionCheck',

View file

@ -0,0 +1,98 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class SystemConfigLibraryDto {
/// Returns a new [SystemConfigLibraryDto] instance.
SystemConfigLibraryDto({
required this.scan,
});
SystemConfigLibraryScanDto scan;
@override
bool operator ==(Object other) => identical(this, other) || other is SystemConfigLibraryDto &&
other.scan == scan;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(scan.hashCode);
@override
String toString() => 'SystemConfigLibraryDto[scan=$scan]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
json[r'scan'] = this.scan;
return json;
}
/// Returns a new [SystemConfigLibraryDto] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static SystemConfigLibraryDto? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
return SystemConfigLibraryDto(
scan: SystemConfigLibraryScanDto.fromJson(json[r'scan'])!,
);
}
return null;
}
static List<SystemConfigLibraryDto> listFromJson(dynamic json, {bool growable = false,}) {
final result = <SystemConfigLibraryDto>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = SystemConfigLibraryDto.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, SystemConfigLibraryDto> mapFromJson(dynamic json) {
final map = <String, SystemConfigLibraryDto>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = SystemConfigLibraryDto.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of SystemConfigLibraryDto-objects as value to a dart map
static Map<String, List<SystemConfigLibraryDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
final map = <String, List<SystemConfigLibraryDto>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = SystemConfigLibraryDto.listFromJson(entry.value, growable: growable,);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{
'scan',
};
}

View file

@ -0,0 +1,106 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class SystemConfigLibraryScanDto {
/// Returns a new [SystemConfigLibraryScanDto] instance.
SystemConfigLibraryScanDto({
required this.cronExpression,
required this.enabled,
});
String cronExpression;
bool enabled;
@override
bool operator ==(Object other) => identical(this, other) || other is SystemConfigLibraryScanDto &&
other.cronExpression == cronExpression &&
other.enabled == enabled;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(cronExpression.hashCode) +
(enabled.hashCode);
@override
String toString() => 'SystemConfigLibraryScanDto[cronExpression=$cronExpression, enabled=$enabled]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
json[r'cronExpression'] = this.cronExpression;
json[r'enabled'] = this.enabled;
return json;
}
/// Returns a new [SystemConfigLibraryScanDto] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static SystemConfigLibraryScanDto? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
return SystemConfigLibraryScanDto(
cronExpression: mapValueOfType<String>(json, r'cronExpression')!,
enabled: mapValueOfType<bool>(json, r'enabled')!,
);
}
return null;
}
static List<SystemConfigLibraryScanDto> listFromJson(dynamic json, {bool growable = false,}) {
final result = <SystemConfigLibraryScanDto>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = SystemConfigLibraryScanDto.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, SystemConfigLibraryScanDto> mapFromJson(dynamic json) {
final map = <String, SystemConfigLibraryScanDto>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = SystemConfigLibraryScanDto.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of SystemConfigLibraryScanDto-objects as value to a dart map
static Map<String, List<SystemConfigLibraryScanDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
final map = <String, List<SystemConfigLibraryScanDto>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = SystemConfigLibraryScanDto.listFromJson(entry.value, growable: growable,);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{
'cronExpression',
'enabled',
};
}