You've already forked immich
mirror of
https://github.com/immich-app/immich.git
synced 2025-08-09 23:17:29 +02:00
feat(server): separate face clustering job (#5598)
* separate facial clustering job * update api * fixed some tests * invert clustering * hdbscan * update api * remove commented code * wip dbscan * cleanup removed cluster endpoint remove commented code * fixes updated tests minor fixes and formatting fixed queuing refinements * scale search range based on library size * defer non-core faces * optimizations removed unused query option * assign faces individually for correctness fixed unit tests remove unused method * don't select face embedding update sql linting fixed ml typing * updated job mock * paginate people query * select face embeddings because typeorm * fix setting face detection concurrency * update sql formatting linting * simplify logic remove unused imports * more specific delete signature * more accurate typing for face stubs * add migration formatting * chore: better typing * don't select embedding by default remove unused import * updated sql * use normal try/catch * stricter concurrency typing and enforcement * update api * update job concurrency panel to show disabled queues formatting * check jobId in queueAll fix tests * remove outdated comment * better facial recognition icon * wording wording formatting * fixed tests * fix * formatting & sql * try to fix sql check * more detailed description * update sql * formatting * wording * update `minFaces` description --------- Co-authored-by: Jason Rasmussen <jrasm91@gmail.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
3
mobile/openapi/doc/AllJobStatusResponseDto.md
generated
3
mobile/openapi/doc/AllJobStatusResponseDto.md
generated
@@ -9,10 +9,11 @@ import 'package:openapi/api.dart';
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**backgroundTask** | [**JobStatusDto**](JobStatusDto.md) | |
|
||||
**faceDetection** | [**JobStatusDto**](JobStatusDto.md) | |
|
||||
**facialRecognition** | [**JobStatusDto**](JobStatusDto.md) | |
|
||||
**library_** | [**JobStatusDto**](JobStatusDto.md) | |
|
||||
**metadataExtraction** | [**JobStatusDto**](JobStatusDto.md) | |
|
||||
**migration** | [**JobStatusDto**](JobStatusDto.md) | |
|
||||
**recognizeFaces** | [**JobStatusDto**](JobStatusDto.md) | |
|
||||
**search** | [**JobStatusDto**](JobStatusDto.md) | |
|
||||
**sidecar** | [**JobStatusDto**](JobStatusDto.md) | |
|
||||
**smartSearch** | [**JobStatusDto**](JobStatusDto.md) | |
|
||||
|
4
mobile/openapi/doc/RecognitionConfig.md
generated
4
mobile/openapi/doc/RecognitionConfig.md
generated
@@ -9,9 +9,9 @@ import 'package:openapi/api.dart';
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**enabled** | **bool** | |
|
||||
**maxDistance** | **int** | |
|
||||
**maxDistance** | **double** | |
|
||||
**minFaces** | **int** | |
|
||||
**minScore** | **int** | |
|
||||
**minScore** | **double** | |
|
||||
**modelName** | **String** | |
|
||||
**modelType** | [**ModelType**](ModelType.md) | | [optional]
|
||||
|
||||
|
2
mobile/openapi/doc/SystemConfigJobDto.md
generated
2
mobile/openapi/doc/SystemConfigJobDto.md
generated
@@ -9,10 +9,10 @@ import 'package:openapi/api.dart';
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**backgroundTask** | [**JobSettingsDto**](JobSettingsDto.md) | |
|
||||
**faceDetection** | [**JobSettingsDto**](JobSettingsDto.md) | |
|
||||
**library_** | [**JobSettingsDto**](JobSettingsDto.md) | |
|
||||
**metadataExtraction** | [**JobSettingsDto**](JobSettingsDto.md) | |
|
||||
**migration** | [**JobSettingsDto**](JobSettingsDto.md) | |
|
||||
**recognizeFaces** | [**JobSettingsDto**](JobSettingsDto.md) | |
|
||||
**search** | [**JobSettingsDto**](JobSettingsDto.md) | |
|
||||
**sidecar** | [**JobSettingsDto**](JobSettingsDto.md) | |
|
||||
**smartSearch** | [**JobSettingsDto**](JobSettingsDto.md) | |
|
||||
|
@@ -14,10 +14,11 @@ class AllJobStatusResponseDto {
|
||||
/// Returns a new [AllJobStatusResponseDto] instance.
|
||||
AllJobStatusResponseDto({
|
||||
required this.backgroundTask,
|
||||
required this.faceDetection,
|
||||
required this.facialRecognition,
|
||||
required this.library_,
|
||||
required this.metadataExtraction,
|
||||
required this.migration,
|
||||
required this.recognizeFaces,
|
||||
required this.search,
|
||||
required this.sidecar,
|
||||
required this.smartSearch,
|
||||
@@ -28,14 +29,16 @@ class AllJobStatusResponseDto {
|
||||
|
||||
JobStatusDto backgroundTask;
|
||||
|
||||
JobStatusDto faceDetection;
|
||||
|
||||
JobStatusDto facialRecognition;
|
||||
|
||||
JobStatusDto library_;
|
||||
|
||||
JobStatusDto metadataExtraction;
|
||||
|
||||
JobStatusDto migration;
|
||||
|
||||
JobStatusDto recognizeFaces;
|
||||
|
||||
JobStatusDto search;
|
||||
|
||||
JobStatusDto sidecar;
|
||||
@@ -51,10 +54,11 @@ class AllJobStatusResponseDto {
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is AllJobStatusResponseDto &&
|
||||
other.backgroundTask == backgroundTask &&
|
||||
other.faceDetection == faceDetection &&
|
||||
other.facialRecognition == facialRecognition &&
|
||||
other.library_ == library_ &&
|
||||
other.metadataExtraction == metadataExtraction &&
|
||||
other.migration == migration &&
|
||||
other.recognizeFaces == recognizeFaces &&
|
||||
other.search == search &&
|
||||
other.sidecar == sidecar &&
|
||||
other.smartSearch == smartSearch &&
|
||||
@@ -66,10 +70,11 @@ class AllJobStatusResponseDto {
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(backgroundTask.hashCode) +
|
||||
(faceDetection.hashCode) +
|
||||
(facialRecognition.hashCode) +
|
||||
(library_.hashCode) +
|
||||
(metadataExtraction.hashCode) +
|
||||
(migration.hashCode) +
|
||||
(recognizeFaces.hashCode) +
|
||||
(search.hashCode) +
|
||||
(sidecar.hashCode) +
|
||||
(smartSearch.hashCode) +
|
||||
@@ -78,15 +83,16 @@ class AllJobStatusResponseDto {
|
||||
(videoConversion.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AllJobStatusResponseDto[backgroundTask=$backgroundTask, library_=$library_, metadataExtraction=$metadataExtraction, migration=$migration, recognizeFaces=$recognizeFaces, search=$search, sidecar=$sidecar, smartSearch=$smartSearch, storageTemplateMigration=$storageTemplateMigration, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion]';
|
||||
String toString() => 'AllJobStatusResponseDto[backgroundTask=$backgroundTask, faceDetection=$faceDetection, facialRecognition=$facialRecognition, library_=$library_, metadataExtraction=$metadataExtraction, migration=$migration, search=$search, sidecar=$sidecar, smartSearch=$smartSearch, storageTemplateMigration=$storageTemplateMigration, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'backgroundTask'] = this.backgroundTask;
|
||||
json[r'faceDetection'] = this.faceDetection;
|
||||
json[r'facialRecognition'] = this.facialRecognition;
|
||||
json[r'library'] = this.library_;
|
||||
json[r'metadataExtraction'] = this.metadataExtraction;
|
||||
json[r'migration'] = this.migration;
|
||||
json[r'recognizeFaces'] = this.recognizeFaces;
|
||||
json[r'search'] = this.search;
|
||||
json[r'sidecar'] = this.sidecar;
|
||||
json[r'smartSearch'] = this.smartSearch;
|
||||
@@ -105,10 +111,11 @@ class AllJobStatusResponseDto {
|
||||
|
||||
return AllJobStatusResponseDto(
|
||||
backgroundTask: JobStatusDto.fromJson(json[r'backgroundTask'])!,
|
||||
faceDetection: JobStatusDto.fromJson(json[r'faceDetection'])!,
|
||||
facialRecognition: JobStatusDto.fromJson(json[r'facialRecognition'])!,
|
||||
library_: JobStatusDto.fromJson(json[r'library'])!,
|
||||
metadataExtraction: JobStatusDto.fromJson(json[r'metadataExtraction'])!,
|
||||
migration: JobStatusDto.fromJson(json[r'migration'])!,
|
||||
recognizeFaces: JobStatusDto.fromJson(json[r'recognizeFaces'])!,
|
||||
search: JobStatusDto.fromJson(json[r'search'])!,
|
||||
sidecar: JobStatusDto.fromJson(json[r'sidecar'])!,
|
||||
smartSearch: JobStatusDto.fromJson(json[r'smartSearch'])!,
|
||||
@@ -163,10 +170,11 @@ class AllJobStatusResponseDto {
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'backgroundTask',
|
||||
'faceDetection',
|
||||
'facialRecognition',
|
||||
'library',
|
||||
'metadataExtraction',
|
||||
'migration',
|
||||
'recognizeFaces',
|
||||
'search',
|
||||
'sidecar',
|
||||
'smartSearch',
|
||||
|
9
mobile/openapi/lib/model/job_name.dart
generated
9
mobile/openapi/lib/model/job_name.dart
generated
@@ -26,7 +26,8 @@ class JobName {
|
||||
static const thumbnailGeneration = JobName._(r'thumbnailGeneration');
|
||||
static const metadataExtraction = JobName._(r'metadataExtraction');
|
||||
static const videoConversion = JobName._(r'videoConversion');
|
||||
static const recognizeFaces = JobName._(r'recognizeFaces');
|
||||
static const faceDetection = JobName._(r'faceDetection');
|
||||
static const facialRecognition = JobName._(r'facialRecognition');
|
||||
static const smartSearch = JobName._(r'smartSearch');
|
||||
static const backgroundTask = JobName._(r'backgroundTask');
|
||||
static const storageTemplateMigration = JobName._(r'storageTemplateMigration');
|
||||
@@ -40,7 +41,8 @@ class JobName {
|
||||
thumbnailGeneration,
|
||||
metadataExtraction,
|
||||
videoConversion,
|
||||
recognizeFaces,
|
||||
faceDetection,
|
||||
facialRecognition,
|
||||
smartSearch,
|
||||
backgroundTask,
|
||||
storageTemplateMigration,
|
||||
@@ -89,7 +91,8 @@ class JobNameTypeTransformer {
|
||||
case r'thumbnailGeneration': return JobName.thumbnailGeneration;
|
||||
case r'metadataExtraction': return JobName.metadataExtraction;
|
||||
case r'videoConversion': return JobName.videoConversion;
|
||||
case r'recognizeFaces': return JobName.recognizeFaces;
|
||||
case r'faceDetection': return JobName.faceDetection;
|
||||
case r'facialRecognition': return JobName.facialRecognition;
|
||||
case r'smartSearch': return JobName.smartSearch;
|
||||
case r'backgroundTask': return JobName.backgroundTask;
|
||||
case r'storageTemplateMigration': return JobName.storageTemplateMigration;
|
||||
|
8
mobile/openapi/lib/model/recognition_config.dart
generated
8
mobile/openapi/lib/model/recognition_config.dart
generated
@@ -23,11 +23,11 @@ class RecognitionConfig {
|
||||
|
||||
bool enabled;
|
||||
|
||||
int maxDistance;
|
||||
double maxDistance;
|
||||
|
||||
int minFaces;
|
||||
|
||||
int minScore;
|
||||
double minScore;
|
||||
|
||||
String modelName;
|
||||
|
||||
@@ -85,9 +85,9 @@ class RecognitionConfig {
|
||||
|
||||
return RecognitionConfig(
|
||||
enabled: mapValueOfType<bool>(json, r'enabled')!,
|
||||
maxDistance: mapValueOfType<int>(json, r'maxDistance')!,
|
||||
maxDistance: mapValueOfType<double>(json, r'maxDistance')!,
|
||||
minFaces: mapValueOfType<int>(json, r'minFaces')!,
|
||||
minScore: mapValueOfType<int>(json, r'minScore')!,
|
||||
minScore: mapValueOfType<double>(json, r'minScore')!,
|
||||
modelName: mapValueOfType<String>(json, r'modelName')!,
|
||||
modelType: ModelType.fromJson(json[r'modelType']),
|
||||
);
|
||||
|
18
mobile/openapi/lib/model/system_config_job_dto.dart
generated
18
mobile/openapi/lib/model/system_config_job_dto.dart
generated
@@ -14,10 +14,10 @@ class SystemConfigJobDto {
|
||||
/// Returns a new [SystemConfigJobDto] instance.
|
||||
SystemConfigJobDto({
|
||||
required this.backgroundTask,
|
||||
required this.faceDetection,
|
||||
required this.library_,
|
||||
required this.metadataExtraction,
|
||||
required this.migration,
|
||||
required this.recognizeFaces,
|
||||
required this.search,
|
||||
required this.sidecar,
|
||||
required this.smartSearch,
|
||||
@@ -27,14 +27,14 @@ class SystemConfigJobDto {
|
||||
|
||||
JobSettingsDto backgroundTask;
|
||||
|
||||
JobSettingsDto faceDetection;
|
||||
|
||||
JobSettingsDto library_;
|
||||
|
||||
JobSettingsDto metadataExtraction;
|
||||
|
||||
JobSettingsDto migration;
|
||||
|
||||
JobSettingsDto recognizeFaces;
|
||||
|
||||
JobSettingsDto search;
|
||||
|
||||
JobSettingsDto sidecar;
|
||||
@@ -48,10 +48,10 @@ class SystemConfigJobDto {
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is SystemConfigJobDto &&
|
||||
other.backgroundTask == backgroundTask &&
|
||||
other.faceDetection == faceDetection &&
|
||||
other.library_ == library_ &&
|
||||
other.metadataExtraction == metadataExtraction &&
|
||||
other.migration == migration &&
|
||||
other.recognizeFaces == recognizeFaces &&
|
||||
other.search == search &&
|
||||
other.sidecar == sidecar &&
|
||||
other.smartSearch == smartSearch &&
|
||||
@@ -62,10 +62,10 @@ class SystemConfigJobDto {
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(backgroundTask.hashCode) +
|
||||
(faceDetection.hashCode) +
|
||||
(library_.hashCode) +
|
||||
(metadataExtraction.hashCode) +
|
||||
(migration.hashCode) +
|
||||
(recognizeFaces.hashCode) +
|
||||
(search.hashCode) +
|
||||
(sidecar.hashCode) +
|
||||
(smartSearch.hashCode) +
|
||||
@@ -73,15 +73,15 @@ class SystemConfigJobDto {
|
||||
(videoConversion.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'SystemConfigJobDto[backgroundTask=$backgroundTask, library_=$library_, metadataExtraction=$metadataExtraction, migration=$migration, recognizeFaces=$recognizeFaces, search=$search, sidecar=$sidecar, smartSearch=$smartSearch, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion]';
|
||||
String toString() => 'SystemConfigJobDto[backgroundTask=$backgroundTask, faceDetection=$faceDetection, library_=$library_, metadataExtraction=$metadataExtraction, migration=$migration, search=$search, sidecar=$sidecar, smartSearch=$smartSearch, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'backgroundTask'] = this.backgroundTask;
|
||||
json[r'faceDetection'] = this.faceDetection;
|
||||
json[r'library'] = this.library_;
|
||||
json[r'metadataExtraction'] = this.metadataExtraction;
|
||||
json[r'migration'] = this.migration;
|
||||
json[r'recognizeFaces'] = this.recognizeFaces;
|
||||
json[r'search'] = this.search;
|
||||
json[r'sidecar'] = this.sidecar;
|
||||
json[r'smartSearch'] = this.smartSearch;
|
||||
@@ -99,10 +99,10 @@ class SystemConfigJobDto {
|
||||
|
||||
return SystemConfigJobDto(
|
||||
backgroundTask: JobSettingsDto.fromJson(json[r'backgroundTask'])!,
|
||||
faceDetection: JobSettingsDto.fromJson(json[r'faceDetection'])!,
|
||||
library_: JobSettingsDto.fromJson(json[r'library'])!,
|
||||
metadataExtraction: JobSettingsDto.fromJson(json[r'metadataExtraction'])!,
|
||||
migration: JobSettingsDto.fromJson(json[r'migration'])!,
|
||||
recognizeFaces: JobSettingsDto.fromJson(json[r'recognizeFaces'])!,
|
||||
search: JobSettingsDto.fromJson(json[r'search'])!,
|
||||
sidecar: JobSettingsDto.fromJson(json[r'sidecar'])!,
|
||||
smartSearch: JobSettingsDto.fromJson(json[r'smartSearch'])!,
|
||||
@@ -156,10 +156,10 @@ class SystemConfigJobDto {
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'backgroundTask',
|
||||
'faceDetection',
|
||||
'library',
|
||||
'metadataExtraction',
|
||||
'migration',
|
||||
'recognizeFaces',
|
||||
'search',
|
||||
'sidecar',
|
||||
'smartSearch',
|
||||
|
@@ -21,6 +21,16 @@ void main() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// JobStatusDto faceDetection
|
||||
test('to test the property `faceDetection`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// JobStatusDto facialRecognition
|
||||
test('to test the property `facialRecognition`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// JobStatusDto library_
|
||||
test('to test the property `library_`', () async {
|
||||
// TODO
|
||||
@@ -36,11 +46,6 @@ void main() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// JobStatusDto recognizeFaces
|
||||
test('to test the property `recognizeFaces`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// JobStatusDto search
|
||||
test('to test the property `search`', () async {
|
||||
// TODO
|
||||
|
4
mobile/openapi/test/recognition_config_test.dart
generated
4
mobile/openapi/test/recognition_config_test.dart
generated
@@ -21,7 +21,7 @@ void main() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int maxDistance
|
||||
// double maxDistance
|
||||
test('to test the property `maxDistance`', () async {
|
||||
// TODO
|
||||
});
|
||||
@@ -31,7 +31,7 @@ void main() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int minScore
|
||||
// double minScore
|
||||
test('to test the property `minScore`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
10
mobile/openapi/test/system_config_job_dto_test.dart
generated
10
mobile/openapi/test/system_config_job_dto_test.dart
generated
@@ -21,6 +21,11 @@ void main() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// JobSettingsDto faceDetection
|
||||
test('to test the property `faceDetection`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// JobSettingsDto library_
|
||||
test('to test the property `library_`', () async {
|
||||
// TODO
|
||||
@@ -36,11 +41,6 @@ void main() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// JobSettingsDto recognizeFaces
|
||||
test('to test the property `recognizeFaces`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// JobSettingsDto search
|
||||
test('to test the property `search`', () async {
|
||||
// TODO
|
||||
|
Reference in New Issue
Block a user