mirror of
https://github.com/immich-app/immich.git
synced 2025-05-23 17:03:01 -04:00
wip
This commit is contained in:
parent
14970c5539
commit
5b0ea3397f
@ -18,6 +18,7 @@ class AllJobStatusResponseDto {
|
||||
required this.duplicateDetection,
|
||||
required this.faceDetection,
|
||||
required this.facialRecognition,
|
||||
required this.integrityDatabaseCheck,
|
||||
required this.library_,
|
||||
required this.metadataExtraction,
|
||||
required this.migration,
|
||||
@ -40,6 +41,8 @@ class AllJobStatusResponseDto {
|
||||
|
||||
JobStatusDto facialRecognition;
|
||||
|
||||
JobStatusDto integrityDatabaseCheck;
|
||||
|
||||
JobStatusDto library_;
|
||||
|
||||
JobStatusDto metadataExtraction;
|
||||
@ -67,6 +70,7 @@ class AllJobStatusResponseDto {
|
||||
other.duplicateDetection == duplicateDetection &&
|
||||
other.faceDetection == faceDetection &&
|
||||
other.facialRecognition == facialRecognition &&
|
||||
other.integrityDatabaseCheck == integrityDatabaseCheck &&
|
||||
other.library_ == library_ &&
|
||||
other.metadataExtraction == metadataExtraction &&
|
||||
other.migration == migration &&
|
||||
@ -86,6 +90,7 @@ class AllJobStatusResponseDto {
|
||||
(duplicateDetection.hashCode) +
|
||||
(faceDetection.hashCode) +
|
||||
(facialRecognition.hashCode) +
|
||||
(integrityDatabaseCheck.hashCode) +
|
||||
(library_.hashCode) +
|
||||
(metadataExtraction.hashCode) +
|
||||
(migration.hashCode) +
|
||||
@ -98,7 +103,7 @@ class AllJobStatusResponseDto {
|
||||
(videoConversion.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AllJobStatusResponseDto[backgroundTask=$backgroundTask, backupDatabase=$backupDatabase, duplicateDetection=$duplicateDetection, faceDetection=$faceDetection, facialRecognition=$facialRecognition, library_=$library_, metadataExtraction=$metadataExtraction, migration=$migration, notifications=$notifications, search=$search, sidecar=$sidecar, smartSearch=$smartSearch, storageTemplateMigration=$storageTemplateMigration, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion]';
|
||||
String toString() => 'AllJobStatusResponseDto[backgroundTask=$backgroundTask, backupDatabase=$backupDatabase, duplicateDetection=$duplicateDetection, faceDetection=$faceDetection, facialRecognition=$facialRecognition, integrityDatabaseCheck=$integrityDatabaseCheck, library_=$library_, metadataExtraction=$metadataExtraction, migration=$migration, notifications=$notifications, search=$search, sidecar=$sidecar, smartSearch=$smartSearch, storageTemplateMigration=$storageTemplateMigration, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
@ -107,6 +112,7 @@ class AllJobStatusResponseDto {
|
||||
json[r'duplicateDetection'] = this.duplicateDetection;
|
||||
json[r'faceDetection'] = this.faceDetection;
|
||||
json[r'facialRecognition'] = this.facialRecognition;
|
||||
json[r'integrityDatabaseCheck'] = this.integrityDatabaseCheck;
|
||||
json[r'library'] = this.library_;
|
||||
json[r'metadataExtraction'] = this.metadataExtraction;
|
||||
json[r'migration'] = this.migration;
|
||||
@ -134,6 +140,7 @@ class AllJobStatusResponseDto {
|
||||
duplicateDetection: JobStatusDto.fromJson(json[r'duplicateDetection'])!,
|
||||
faceDetection: JobStatusDto.fromJson(json[r'faceDetection'])!,
|
||||
facialRecognition: JobStatusDto.fromJson(json[r'facialRecognition'])!,
|
||||
integrityDatabaseCheck: JobStatusDto.fromJson(json[r'integrityDatabaseCheck'])!,
|
||||
library_: JobStatusDto.fromJson(json[r'library'])!,
|
||||
metadataExtraction: JobStatusDto.fromJson(json[r'metadataExtraction'])!,
|
||||
migration: JobStatusDto.fromJson(json[r'migration'])!,
|
||||
@ -196,6 +203,7 @@ class AllJobStatusResponseDto {
|
||||
'duplicateDetection',
|
||||
'faceDetection',
|
||||
'facialRecognition',
|
||||
'integrityDatabaseCheck',
|
||||
'library',
|
||||
'metadataExtraction',
|
||||
'migration',
|
||||
|
3
mobile/openapi/lib/model/job_name.dart
generated
3
mobile/openapi/lib/model/job_name.dart
generated
@ -38,6 +38,7 @@ class JobName {
|
||||
static const library_ = JobName._(r'library');
|
||||
static const notifications = JobName._(r'notifications');
|
||||
static const backupDatabase = JobName._(r'backupDatabase');
|
||||
static const integrityDatabaseCheck = JobName._(r'integrityDatabaseCheck');
|
||||
|
||||
/// List of all possible values in this [enum][JobName].
|
||||
static const values = <JobName>[
|
||||
@ -56,6 +57,7 @@ class JobName {
|
||||
library_,
|
||||
notifications,
|
||||
backupDatabase,
|
||||
integrityDatabaseCheck,
|
||||
];
|
||||
|
||||
static JobName? fromJson(dynamic value) => JobNameTypeTransformer().decode(value);
|
||||
@ -109,6 +111,7 @@ class JobNameTypeTransformer {
|
||||
case r'library': return JobName.library_;
|
||||
case r'notifications': return JobName.notifications;
|
||||
case r'backupDatabase': return JobName.backupDatabase;
|
||||
case r'integrityDatabaseCheck': return JobName.integrityDatabaseCheck;
|
||||
default:
|
||||
if (!allowNull) {
|
||||
throw ArgumentError('Unknown enum value to decode: $data');
|
||||
|
3
mobile/openapi/lib/model/manual_job_name.dart
generated
3
mobile/openapi/lib/model/manual_job_name.dart
generated
@ -29,6 +29,7 @@ class ManualJobName {
|
||||
static const memoryCleanup = ManualJobName._(r'memory-cleanup');
|
||||
static const memoryCreate = ManualJobName._(r'memory-create');
|
||||
static const backupDatabase = ManualJobName._(r'backup-database');
|
||||
static const integrityDatabaseCheck = ManualJobName._(r'integrity-database-check');
|
||||
|
||||
/// List of all possible values in this [enum][ManualJobName].
|
||||
static const values = <ManualJobName>[
|
||||
@ -38,6 +39,7 @@ class ManualJobName {
|
||||
memoryCleanup,
|
||||
memoryCreate,
|
||||
backupDatabase,
|
||||
integrityDatabaseCheck,
|
||||
];
|
||||
|
||||
static ManualJobName? fromJson(dynamic value) => ManualJobNameTypeTransformer().decode(value);
|
||||
@ -82,6 +84,7 @@ class ManualJobNameTypeTransformer {
|
||||
case r'memory-cleanup': return ManualJobName.memoryCleanup;
|
||||
case r'memory-create': return ManualJobName.memoryCreate;
|
||||
case r'backup-database': return ManualJobName.backupDatabase;
|
||||
case r'integrity-database-check': return ManualJobName.integrityDatabaseCheck;
|
||||
default:
|
||||
if (!allowNull) {
|
||||
throw ArgumentError('Unknown enum value to decode: $data');
|
||||
|
@ -8532,6 +8532,9 @@
|
||||
"facialRecognition": {
|
||||
"$ref": "#/components/schemas/JobStatusDto"
|
||||
},
|
||||
"integrityDatabaseCheck": {
|
||||
"$ref": "#/components/schemas/JobStatusDto"
|
||||
},
|
||||
"library": {
|
||||
"$ref": "#/components/schemas/JobStatusDto"
|
||||
},
|
||||
@ -8569,6 +8572,7 @@
|
||||
"duplicateDetection",
|
||||
"faceDetection",
|
||||
"facialRecognition",
|
||||
"integrityDatabaseCheck",
|
||||
"library",
|
||||
"metadataExtraction",
|
||||
"migration",
|
||||
@ -10101,7 +10105,8 @@
|
||||
"sidecar",
|
||||
"library",
|
||||
"notifications",
|
||||
"backupDatabase"
|
||||
"backupDatabase",
|
||||
"integrityDatabaseCheck"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@ -10336,7 +10341,8 @@
|
||||
"user-cleanup",
|
||||
"memory-cleanup",
|
||||
"memory-create",
|
||||
"backup-database"
|
||||
"backup-database",
|
||||
"integrity-database-check"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -622,6 +622,7 @@ export type AllJobStatusResponseDto = {
|
||||
duplicateDetection: JobStatusDto;
|
||||
faceDetection: JobStatusDto;
|
||||
facialRecognition: JobStatusDto;
|
||||
integrityDatabaseCheck: JobStatusDto;
|
||||
library: JobStatusDto;
|
||||
metadataExtraction: JobStatusDto;
|
||||
migration: JobStatusDto;
|
||||
@ -3789,7 +3790,8 @@ export enum ManualJobName {
|
||||
UserCleanup = "user-cleanup",
|
||||
MemoryCleanup = "memory-cleanup",
|
||||
MemoryCreate = "memory-create",
|
||||
BackupDatabase = "backup-database"
|
||||
BackupDatabase = "backup-database",
|
||||
IntegrityDatabaseCheck = "integrity-database-check"
|
||||
}
|
||||
export enum JobName {
|
||||
ThumbnailGeneration = "thumbnailGeneration",
|
||||
@ -3806,7 +3808,8 @@ export enum JobName {
|
||||
Sidecar = "sidecar",
|
||||
Library = "library",
|
||||
Notifications = "notifications",
|
||||
BackupDatabase = "backupDatabase"
|
||||
BackupDatabase = "backupDatabase",
|
||||
IntegrityDatabaseCheck = "integrityDatabaseCheck"
|
||||
}
|
||||
export enum JobCommand {
|
||||
Start = "start",
|
||||
|
@ -99,4 +99,7 @@ export class AllJobStatusResponseDto implements Record<QueueName, JobStatusDto>
|
||||
|
||||
@ApiProperty({ type: JobStatusDto })
|
||||
[QueueName.BACKUP_DATABASE]!: JobStatusDto;
|
||||
|
||||
@ApiProperty({ type: JobStatusDto })
|
||||
[QueueName.DATABASE_INTEGRITY_CHECK]!: JobStatusDto;
|
||||
}
|
||||
|
@ -251,6 +251,7 @@ export enum ManualJobName {
|
||||
MEMORY_CLEANUP = 'memory-cleanup',
|
||||
MEMORY_CREATE = 'memory-create',
|
||||
BACKUP_DATABASE = 'backup-database',
|
||||
INTEGRITY_DATABASE_CHECK = 'integrity-database-check',
|
||||
}
|
||||
|
||||
export enum AssetPathType {
|
||||
@ -441,6 +442,7 @@ export enum QueueName {
|
||||
LIBRARY = 'library',
|
||||
NOTIFICATION = 'notifications',
|
||||
BACKUP_DATABASE = 'backupDatabase',
|
||||
DATABASE_INTEGRITY_CHECK = 'integrityDatabaseCheck',
|
||||
}
|
||||
|
||||
export enum JobName {
|
||||
@ -532,6 +534,9 @@ export enum JobName {
|
||||
|
||||
// Version check
|
||||
VERSION_CHECK = 'version-check',
|
||||
|
||||
// Integrity
|
||||
DATABASE_INTEGRITY_CHECK = 'database-integrity-check',
|
||||
}
|
||||
|
||||
export enum JobCommand {
|
||||
|
@ -463,3 +463,12 @@ where
|
||||
and "libraryId" = $2::uuid
|
||||
and "isExternal" = $3
|
||||
)
|
||||
|
||||
-- AssetRepository.integrityCheckExif
|
||||
select
|
||||
"id"
|
||||
from
|
||||
"assets"
|
||||
left join "exif" on "assets"."id" = "exif"."assetId"
|
||||
where
|
||||
"exif"."assetId" is null
|
||||
|
@ -875,4 +875,16 @@ export class AssetRepository {
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@GenerateSql()
|
||||
async integrityCheckExif(): Promise<string[]> {
|
||||
const result = await this.db
|
||||
.selectFrom('assets')
|
||||
.select('id')
|
||||
.leftJoin('exif', 'assets.id', 'exif.assetId')
|
||||
.where('exif.assetId', 'is', null)
|
||||
.execute();
|
||||
|
||||
return result.map((row) => row.id);
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import { CliService } from 'src/services/cli.service';
|
||||
import { DatabaseService } from 'src/services/database.service';
|
||||
import { DownloadService } from 'src/services/download.service';
|
||||
import { DuplicateService } from 'src/services/duplicate.service';
|
||||
import { IntegrityService } from 'src/services/integrity.service';
|
||||
import { JobService } from 'src/services/job.service';
|
||||
import { LibraryService } from 'src/services/library.service';
|
||||
import { MapService } from 'src/services/map.service';
|
||||
@ -54,6 +55,7 @@ export const services = [
|
||||
DatabaseService,
|
||||
DownloadService,
|
||||
DuplicateService,
|
||||
IntegrityService,
|
||||
JobService,
|
||||
LibraryService,
|
||||
MapService,
|
||||
|
13
server/src/services/integrity.service.ts
Normal file
13
server/src/services/integrity.service.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { OnJob } from 'src/decorators';
|
||||
import { JobName, JobStatus, QueueName } from 'src/enum';
|
||||
import { BaseService } from 'src/services/base.service';
|
||||
|
||||
@Injectable()
|
||||
export class IntegrityService extends BaseService {
|
||||
@OnJob({ name: JobName.DATABASE_INTEGRITY_CHECK, queue: QueueName.DATABASE_INTEGRITY_CHECK })
|
||||
async handleDatabaseIntegrityCheck(): Promise<JobStatus> {
|
||||
console.log(JSON.stringify(await this.assetRepository.integrityCheckExif()));
|
||||
return JobStatus.SUCCESS;
|
||||
}
|
||||
}
|
@ -46,6 +46,10 @@ const asJobItem = (dto: JobCreateDto): JobItem => {
|
||||
return { name: JobName.BACKUP_DATABASE };
|
||||
}
|
||||
|
||||
case ManualJobName.INTEGRITY_DATABASE_CHECK: {
|
||||
return { name: JobName.DATABASE_INTEGRITY_CHECK };
|
||||
}
|
||||
|
||||
default: {
|
||||
throw new BadRequestException('Invalid job name');
|
||||
}
|
||||
@ -228,6 +232,7 @@ export class JobService extends BaseService {
|
||||
QueueName.STORAGE_TEMPLATE_MIGRATION,
|
||||
QueueName.DUPLICATE_DETECTION,
|
||||
QueueName.BACKUP_DATABASE,
|
||||
QueueName.DATABASE_INTEGRITY_CHECK,
|
||||
].includes(name);
|
||||
}
|
||||
|
||||
|
@ -164,6 +164,7 @@ export type ConcurrentQueueName = Exclude<
|
||||
| QueueName.FACIAL_RECOGNITION
|
||||
| QueueName.DUPLICATE_DETECTION
|
||||
| QueueName.BACKUP_DATABASE
|
||||
| QueueName.DATABASE_INTEGRITY_CHECK
|
||||
>;
|
||||
|
||||
export type Jobs = { [K in JobItem['name']]: (JobItem & { name: K })['data'] };
|
||||
@ -363,9 +364,8 @@ export type JobItem =
|
||||
// Version check
|
||||
| { name: JobName.VERSION_CHECK; data: IBaseJob }
|
||||
|
||||
// Memories
|
||||
| { name: JobName.MEMORIES_CLEANUP; data?: IBaseJob }
|
||||
| { name: JobName.MEMORIES_CREATE; data?: IBaseJob };
|
||||
// Integrity
|
||||
| { name: JobName.DATABASE_INTEGRITY_CHECK; data?: IBaseJob };
|
||||
|
||||
export type VectorExtension = DatabaseExtension.VECTOR | DatabaseExtension.VECTORS;
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
{ title: $t('admin.memory_cleanup_job'), value: ManualJobName.MemoryCleanup },
|
||||
{ title: $t('admin.memory_generate_job'), value: ManualJobName.MemoryCreate },
|
||||
{ title: $t('admin.backup_database'), value: ManualJobName.BackupDatabase },
|
||||
{ title: 'integrity test', value: ManualJobName.IntegrityDatabaseCheck },
|
||||
].map(({ value, title }) => ({ id: value, label: title, value }));
|
||||
|
||||
let selectedJob: ComboBoxOption | undefined = $state(undefined);
|
||||
|
Loading…
x
Reference in New Issue
Block a user