|
|
|
|
@ -9,7 +9,7 @@ import picomatch from 'picomatch';
|
|
|
|
|
import { AccessCore, Permission } from '../access';
|
|
|
|
|
import { AuthDto } from '../auth';
|
|
|
|
|
import { mimeTypes } from '../domain.constant';
|
|
|
|
|
import { usePagination, validateCronExpression } from '../domain.util';
|
|
|
|
|
import { handlePromiseError, usePagination, validateCronExpression } from '../domain.util';
|
|
|
|
|
import { IBaseJob, IEntityJob, ILibraryFileJob, ILibraryRefreshJob, JOBS_ASSET_PAGINATION_SIZE, JobName } from '../job';
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
@ -43,7 +43,7 @@ export class LibraryService extends EventEmitter {
|
|
|
|
|
private access: AccessCore;
|
|
|
|
|
private configCore: SystemConfigCore;
|
|
|
|
|
private watchLibraries = false;
|
|
|
|
|
private watchers: Record<string, () => void> = {};
|
|
|
|
|
private watchers: Record<string, () => Promise<void>> = {};
|
|
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
|
@Inject(IAccessRepository) accessRepository: IAccessRepository,
|
|
|
|
|
@ -73,7 +73,11 @@ export class LibraryService extends EventEmitter {
|
|
|
|
|
this.jobRepository.addCronJob(
|
|
|
|
|
'libraryScan',
|
|
|
|
|
scan.cronExpression,
|
|
|
|
|
() => this.jobRepository.queue({ name: JobName.LIBRARY_QUEUE_SCAN_ALL, data: { force: false } }),
|
|
|
|
|
() =>
|
|
|
|
|
handlePromiseError(
|
|
|
|
|
this.jobRepository.queue({ name: JobName.LIBRARY_QUEUE_SCAN_ALL, data: { force: false } }),
|
|
|
|
|
this.logger,
|
|
|
|
|
),
|
|
|
|
|
scan.enabled,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
@ -81,12 +85,12 @@ export class LibraryService extends EventEmitter {
|
|
|
|
|
await this.watchAll();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.configCore.config$.subscribe(async ({ library }) => {
|
|
|
|
|
this.configCore.config$.subscribe(({ library }) => {
|
|
|
|
|
this.jobRepository.updateCronJob('libraryScan', library.scan.cronExpression, library.scan.enabled);
|
|
|
|
|
|
|
|
|
|
if (library.watch.enabled !== this.watchLibraries) {
|
|
|
|
|
this.watchLibraries = library.watch.enabled;
|
|
|
|
|
await (this.watchLibraries ? this.watchAll() : this.unwatchAll());
|
|
|
|
|
handlePromiseError(this.watchLibraries ? this.watchAll() : this.unwatchAll(), this.logger);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
@ -124,28 +128,37 @@ export class LibraryService extends EventEmitter {
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
onReady: () => _resolve(),
|
|
|
|
|
onAdd: async (path) => {
|
|
|
|
|
this.logger.debug(`File add event received for ${path} in library ${library.id}}`);
|
|
|
|
|
if (matcher(path)) {
|
|
|
|
|
await this.scanAssets(library.id, [path], library.ownerId, false);
|
|
|
|
|
}
|
|
|
|
|
this.emit('add', path);
|
|
|
|
|
onAdd: (path) => {
|
|
|
|
|
const handler = async () => {
|
|
|
|
|
this.logger.debug(`File add event received for ${path} in library ${library.id}}`);
|
|
|
|
|
if (matcher(path)) {
|
|
|
|
|
await this.scanAssets(library.id, [path], library.ownerId, false);
|
|
|
|
|
}
|
|
|
|
|
this.emit('add', path);
|
|
|
|
|
};
|
|
|
|
|
return handlePromiseError(handler(), this.logger);
|
|
|
|
|
},
|
|
|
|
|
onChange: async (path) => {
|
|
|
|
|
this.logger.debug(`Detected file change for ${path} in library ${library.id}`);
|
|
|
|
|
if (matcher(path)) {
|
|
|
|
|
// Note: if the changed file was not previously imported, it will be imported now.
|
|
|
|
|
await this.scanAssets(library.id, [path], library.ownerId, false);
|
|
|
|
|
}
|
|
|
|
|
this.emit('change', path);
|
|
|
|
|
onChange: (path) => {
|
|
|
|
|
const handler = async () => {
|
|
|
|
|
this.logger.debug(`Detected file change for ${path} in library ${library.id}`);
|
|
|
|
|
if (matcher(path)) {
|
|
|
|
|
// Note: if the changed file was not previously imported, it will be imported now.
|
|
|
|
|
await this.scanAssets(library.id, [path], library.ownerId, false);
|
|
|
|
|
}
|
|
|
|
|
this.emit('change', path);
|
|
|
|
|
};
|
|
|
|
|
return handlePromiseError(handler(), this.logger);
|
|
|
|
|
},
|
|
|
|
|
onUnlink: async (path) => {
|
|
|
|
|
this.logger.debug(`Detected deleted file at ${path} in library ${library.id}`);
|
|
|
|
|
const asset = await this.assetRepository.getByLibraryIdAndOriginalPath(library.id, path);
|
|
|
|
|
if (asset && matcher(path)) {
|
|
|
|
|
await this.assetRepository.save({ id: asset.id, isOffline: true });
|
|
|
|
|
}
|
|
|
|
|
this.emit('unlink', path);
|
|
|
|
|
onUnlink: (path) => {
|
|
|
|
|
const handler = async () => {
|
|
|
|
|
this.logger.debug(`Detected deleted file at ${path} in library ${library.id}`);
|
|
|
|
|
const asset = await this.assetRepository.getByLibraryIdAndOriginalPath(library.id, path);
|
|
|
|
|
if (asset && matcher(path)) {
|
|
|
|
|
await this.assetRepository.save({ id: asset.id, isOffline: true });
|
|
|
|
|
}
|
|
|
|
|
this.emit('unlink', path);
|
|
|
|
|
};
|
|
|
|
|
return handlePromiseError(handler(), this.logger);
|
|
|
|
|
},
|
|
|
|
|
onError: (error) => {
|
|
|
|
|
// TODO: should we log, or throw an exception?
|
|
|
|
|
|