2024-03-20 19:32:04 +01:00
|
|
|
import { JobName, QueueName } from 'src/domain/job/job.constants';
|
2023-03-02 21:47:08 -05:00
|
|
|
import {
|
2023-10-06 07:01:14 +00:00
|
|
|
IAssetDeletionJob,
|
2023-03-20 11:55:28 -04:00
|
|
|
IBaseJob,
|
2024-01-18 00:08:48 -05:00
|
|
|
IDeferrableJob,
|
2023-03-02 21:47:08 -05:00
|
|
|
IDeleteFilesJob,
|
2023-05-26 15:43:24 -04:00
|
|
|
IEntityJob,
|
2023-09-20 13:16:33 +02:00
|
|
|
ILibraryFileJob,
|
|
|
|
|
ILibraryRefreshJob,
|
2023-11-30 04:52:28 +01:00
|
|
|
ISidecarWriteJob,
|
2024-03-20 19:32:04 +01:00
|
|
|
} from 'src/domain/job/job.interface';
|
2023-01-21 23:13:36 -05:00
|
|
|
|
|
|
|
|
export interface JobCounts {
|
|
|
|
|
active: number;
|
|
|
|
|
completed: number;
|
|
|
|
|
failed: number;
|
|
|
|
|
delayed: number;
|
|
|
|
|
waiting: number;
|
2023-03-29 17:33:03 +02:00
|
|
|
paused: number;
|
2023-01-21 23:13:36 -05:00
|
|
|
}
|
2023-01-21 11:11:55 -05:00
|
|
|
|
2023-04-01 22:46:07 +02:00
|
|
|
export interface QueueStatus {
|
|
|
|
|
isActive: boolean;
|
|
|
|
|
isPaused: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-05 10:07:20 +08:00
|
|
|
export enum QueueCleanType {
|
|
|
|
|
FAILED = 'failed',
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-21 11:11:55 -05:00
|
|
|
export type JobItem =
|
2023-03-20 11:55:28 -04:00
|
|
|
// Transcoding
|
|
|
|
|
| { name: JobName.QUEUE_VIDEO_CONVERSION; data: IBaseJob }
|
2023-05-26 15:43:24 -04:00
|
|
|
| { name: JobName.VIDEO_CONVERSION; data: IEntityJob }
|
2023-03-20 11:55:28 -04:00
|
|
|
|
|
|
|
|
// Thumbnails
|
|
|
|
|
| { name: JobName.QUEUE_GENERATE_THUMBNAILS; data: IBaseJob }
|
2023-05-26 15:43:24 -04:00
|
|
|
| { name: JobName.GENERATE_JPEG_THUMBNAIL; data: IEntityJob }
|
|
|
|
|
| { name: JobName.GENERATE_WEBP_THUMBNAIL; data: IEntityJob }
|
2023-06-17 23:22:31 -04:00
|
|
|
| { name: JobName.GENERATE_THUMBHASH_THUMBNAIL; data: IEntityJob }
|
2023-03-20 11:55:28 -04:00
|
|
|
|
2024-01-12 18:43:36 -06:00
|
|
|
// User
|
2023-06-01 06:32:51 -04:00
|
|
|
| { name: JobName.USER_DELETE_CHECK; data?: IBaseJob }
|
2023-05-26 15:43:24 -04:00
|
|
|
| { name: JobName.USER_DELETION; data: IEntityJob }
|
2024-01-12 18:43:36 -06:00
|
|
|
| { name: JobName.USER_SYNC_USAGE; data?: IBaseJob }
|
2023-03-20 11:55:28 -04:00
|
|
|
|
|
|
|
|
// Storage Template
|
2023-06-01 06:32:51 -04:00
|
|
|
| { name: JobName.STORAGE_TEMPLATE_MIGRATION; data?: IBaseJob }
|
2023-05-26 15:43:24 -04:00
|
|
|
| { name: JobName.STORAGE_TEMPLATE_MIGRATION_SINGLE; data: IEntityJob }
|
2023-03-20 11:55:28 -04:00
|
|
|
|
2023-09-25 17:07:21 +02:00
|
|
|
// Migration
|
|
|
|
|
| { name: JobName.QUEUE_MIGRATION; data?: IBaseJob }
|
|
|
|
|
| { name: JobName.MIGRATE_ASSET; data?: IEntityJob }
|
|
|
|
|
| { name: JobName.MIGRATE_PERSON; data?: IEntityJob }
|
|
|
|
|
|
2023-03-20 11:55:28 -04:00
|
|
|
// Metadata Extraction
|
|
|
|
|
| { name: JobName.QUEUE_METADATA_EXTRACTION; data: IBaseJob }
|
2023-05-26 15:43:24 -04:00
|
|
|
| { name: JobName.METADATA_EXTRACTION; data: IEntityJob }
|
2023-08-15 21:34:57 -04:00
|
|
|
| { name: JobName.LINK_LIVE_PHOTOS; data: IEntityJob }
|
feat(server): xmp sidecar metadata (#2466)
* initial commit for XMP sidecar support
* Added support for 'missing' metadata files to include those without sidecar files, now detects sidecar files in the filesystem for media already ingested but the sidecar was created afterwards
* didn't mean to commit default log level during testing
* new sidecar logic for video metadata as well
* Added xml mimetype for sidecars only
* don't need capture group for this regex
* wrong default value reverted
* simplified the move here - keep it in the same try catch since the outcome is to move the media back anyway
* simplified setter logic
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
* simplified logic per suggestions
* sidecar is now its own queue with a discover and sync, updated UI for the new job queueing
* queue a sidecar job for every asset based on discovery or sync, though the logic is almost identical aside from linking the sidecar
* now queue sidecar jobs for each assset, though logic is mostly the same between discovery and sync
* simplified logic of filename extraction and asset instantiation
* not sure how that got deleted..
* updated code per suggestions and comments in the PR
* stat was not being used, removed the variable set
* better type checking, using in-scope variables for exif getter instead of passing in every time
* removed commented out test
* ran and resolved all lints, formats, checks, and tests
* resolved suggested change in PR
* made getExifProperty more dynamic with multiple possible args for fallbacks, fixed typo, used generic in function for better type checking
* better error handling and moving files back to positions on move or save failure
* regenerated api
* format fixes
* Added XMP documentation
* documentation typo
* Merged in main
* missed merge conflict
* more changes due to a merge
* Resolving conflicts
* added icon for sidecar jobs
---------
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-05-24 21:59:30 -04:00
|
|
|
// Sidecar Scanning
|
|
|
|
|
| { name: JobName.QUEUE_SIDECAR; data: IBaseJob }
|
2023-05-26 15:43:24 -04:00
|
|
|
| { name: JobName.SIDECAR_DISCOVERY; data: IEntityJob }
|
|
|
|
|
| { name: JobName.SIDECAR_SYNC; data: IEntityJob }
|
2023-11-30 04:52:28 +01:00
|
|
|
| { name: JobName.SIDECAR_WRITE; data: ISidecarWriteJob }
|
feat(server): xmp sidecar metadata (#2466)
* initial commit for XMP sidecar support
* Added support for 'missing' metadata files to include those without sidecar files, now detects sidecar files in the filesystem for media already ingested but the sidecar was created afterwards
* didn't mean to commit default log level during testing
* new sidecar logic for video metadata as well
* Added xml mimetype for sidecars only
* don't need capture group for this regex
* wrong default value reverted
* simplified the move here - keep it in the same try catch since the outcome is to move the media back anyway
* simplified setter logic
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
* simplified logic per suggestions
* sidecar is now its own queue with a discover and sync, updated UI for the new job queueing
* queue a sidecar job for every asset based on discovery or sync, though the logic is almost identical aside from linking the sidecar
* now queue sidecar jobs for each assset, though logic is mostly the same between discovery and sync
* simplified logic of filename extraction and asset instantiation
* not sure how that got deleted..
* updated code per suggestions and comments in the PR
* stat was not being used, removed the variable set
* better type checking, using in-scope variables for exif getter instead of passing in every time
* removed commented out test
* ran and resolved all lints, formats, checks, and tests
* resolved suggested change in PR
* made getExifProperty more dynamic with multiple possible args for fallbacks, fixed typo, used generic in function for better type checking
* better error handling and moving files back to positions on move or save failure
* regenerated api
* format fixes
* Added XMP documentation
* documentation typo
* Merged in main
* missed merge conflict
* more changes due to a merge
* Resolving conflicts
* added icon for sidecar jobs
---------
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2023-05-24 21:59:30 -04:00
|
|
|
|
2024-01-18 00:08:48 -05:00
|
|
|
// Facial Recognition
|
|
|
|
|
| { name: JobName.QUEUE_FACE_DETECTION; data: IBaseJob }
|
|
|
|
|
| { name: JobName.FACE_DETECTION; data: IEntityJob }
|
|
|
|
|
| { name: JobName.QUEUE_FACIAL_RECOGNITION; data: IBaseJob }
|
|
|
|
|
| { name: JobName.FACIAL_RECOGNITION; data: IDeferrableJob }
|
2023-09-26 03:03:22 -04:00
|
|
|
| { name: JobName.GENERATE_PERSON_THUMBNAIL; data: IEntityJob }
|
2023-05-17 13:07:17 -04:00
|
|
|
|
2024-01-29 09:51:22 -05:00
|
|
|
// Smart Search
|
|
|
|
|
| { name: JobName.QUEUE_SMART_SEARCH; data: IBaseJob }
|
|
|
|
|
| { name: JobName.SMART_SEARCH; data: IEntityJob }
|
2023-03-20 11:55:28 -04:00
|
|
|
|
|
|
|
|
// Filesystem
|
2023-03-02 21:47:08 -05:00
|
|
|
| { name: JobName.DELETE_FILES; data: IDeleteFilesJob }
|
2023-03-20 11:55:28 -04:00
|
|
|
|
2024-01-31 09:15:54 +01:00
|
|
|
// Audit Log Cleanup
|
2023-08-24 21:28:50 +02:00
|
|
|
| { name: JobName.CLEAN_OLD_AUDIT_LOGS; data?: IBaseJob }
|
|
|
|
|
|
2023-05-17 13:07:17 -04:00
|
|
|
// Asset Deletion
|
2023-06-01 06:32:51 -04:00
|
|
|
| { name: JobName.PERSON_CLEANUP; data?: IBaseJob }
|
2023-10-06 07:01:14 +00:00
|
|
|
| { name: JobName.ASSET_DELETION; data: IAssetDeletionJob }
|
|
|
|
|
| { name: JobName.ASSET_DELETION_CHECK; data?: IBaseJob }
|
2023-05-17 13:07:17 -04:00
|
|
|
|
2023-10-24 17:05:42 +02:00
|
|
|
// Library Management
|
2023-09-20 13:16:33 +02:00
|
|
|
| { name: JobName.LIBRARY_SCAN_ASSET; data: ILibraryFileJob }
|
|
|
|
|
| { name: JobName.LIBRARY_SCAN; data: ILibraryRefreshJob }
|
|
|
|
|
| { name: JobName.LIBRARY_REMOVE_OFFLINE; data: IEntityJob }
|
|
|
|
|
| { name: JobName.LIBRARY_DELETE; data: IEntityJob }
|
|
|
|
|
| { name: JobName.LIBRARY_QUEUE_SCAN_ALL; data: IBaseJob }
|
2023-12-08 11:15:46 -05:00
|
|
|
| { name: JobName.LIBRARY_QUEUE_CLEANUP; data: IBaseJob };
|
2023-01-21 11:11:55 -05:00
|
|
|
|
2024-03-15 14:16:54 +01:00
|
|
|
export enum JobStatus {
|
|
|
|
|
SUCCESS = 'success',
|
|
|
|
|
FAILED = 'failed',
|
|
|
|
|
SKIPPED = 'skipped',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type JobHandler<T = any> = (data: T) => Promise<JobStatus>;
|
2023-10-06 17:32:28 -04:00
|
|
|
export type JobItemHandler = (item: JobItem) => Promise<void>;
|
2023-06-01 06:32:51 -04:00
|
|
|
|
2023-01-21 11:11:55 -05:00
|
|
|
export const IJobRepository = 'IJobRepository';
|
|
|
|
|
|
|
|
|
|
export interface IJobRepository {
|
2023-10-06 17:32:28 -04:00
|
|
|
addHandler(queueName: QueueName, concurrency: number, handler: JobItemHandler): void;
|
2023-10-31 21:19:12 +01:00
|
|
|
addCronJob(name: string, expression: string, onTick: () => void, start?: boolean): void;
|
|
|
|
|
updateCronJob(name: string, expression?: string, start?: boolean): void;
|
|
|
|
|
deleteCronJob(name: string): void;
|
2023-06-01 06:32:51 -04:00
|
|
|
setConcurrency(queueName: QueueName, concurrency: number): void;
|
2023-02-25 09:12:03 -05:00
|
|
|
queue(item: JobItem): Promise<void>;
|
2024-01-01 15:45:42 -05:00
|
|
|
queueAll(items: JobItem[]): Promise<void>;
|
2023-03-20 11:55:28 -04:00
|
|
|
pause(name: QueueName): Promise<void>;
|
2023-03-28 14:25:22 -04:00
|
|
|
resume(name: QueueName): Promise<void>;
|
2023-01-21 23:13:36 -05:00
|
|
|
empty(name: QueueName): Promise<void>;
|
2023-12-05 10:07:20 +08:00
|
|
|
clear(name: QueueName, type: QueueCleanType): Promise<string[]>;
|
2023-04-01 22:46:07 +02:00
|
|
|
getQueueStatus(name: QueueName): Promise<QueueStatus>;
|
2023-01-21 23:13:36 -05:00
|
|
|
getJobCounts(name: QueueName): Promise<JobCounts>;
|
2024-01-18 00:08:48 -05:00
|
|
|
waitForQueueCompletion(...queues: QueueName[]): Promise<void>;
|
2023-01-21 11:11:55 -05:00
|
|
|
}
|