mirror of
https://github.com/immich-app/immich.git
synced 2025-12-22 01:11:20 +03:00
86 lines
2.6 KiB
TypeScript
86 lines
2.6 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { JOBS_ASSET_PAGINATION_SIZE } from 'src/constants';
|
|
import { OnEvent, OnJob } from 'src/decorators';
|
|
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
|
import { AuthDto } from 'src/dtos/auth.dto';
|
|
import { TrashResponseDto } from 'src/dtos/trash.dto';
|
|
import { JobName, JobStatus, Permission, QueueName } from 'src/enum';
|
|
import { BaseService } from 'src/services/base.service';
|
|
|
|
@Injectable()
|
|
export class TrashService extends BaseService {
|
|
async restoreAssets(auth: AuthDto, dto: BulkIdsDto): Promise<TrashResponseDto> {
|
|
const { ids } = dto;
|
|
if (ids.length === 0) {
|
|
return { count: 0 };
|
|
}
|
|
|
|
await this.requireAccess({ auth, permission: Permission.AssetDelete, ids });
|
|
await this.trashRepository.restoreAll(ids);
|
|
await this.eventRepository.emit('AssetRestoreAll', { assetIds: ids, userId: auth.user.id });
|
|
|
|
this.logger.log(`Restored ${ids.length} asset(s) from trash`);
|
|
|
|
return { count: ids.length };
|
|
}
|
|
|
|
async restore(auth: AuthDto): Promise<TrashResponseDto> {
|
|
const count = await this.trashRepository.restore(auth.user.id);
|
|
if (count > 0) {
|
|
this.logger.log(`Restored ${count} asset(s) from trash`);
|
|
}
|
|
return { count };
|
|
}
|
|
|
|
async empty(auth: AuthDto): Promise<TrashResponseDto> {
|
|
const count = await this.trashRepository.empty(auth.user.id);
|
|
if (count > 0) {
|
|
await this.jobRepository.queue({ name: JobName.AssetEmptyTrash, data: {} });
|
|
}
|
|
return { count };
|
|
}
|
|
|
|
@OnEvent({ name: 'AssetDeleteAll' })
|
|
async onAssetsDelete() {
|
|
await this.jobRepository.queue({ name: JobName.AssetEmptyTrash, data: {} });
|
|
}
|
|
|
|
@OnJob({ name: JobName.AssetEmptyTrash, queue: QueueName.BackgroundTask })
|
|
async handleEmptyTrash() {
|
|
const assets = this.trashRepository.getDeletedIds();
|
|
|
|
let count = 0;
|
|
const batch: string[] = [];
|
|
for await (const { id } of assets) {
|
|
batch.push(id);
|
|
|
|
if (batch.length === JOBS_ASSET_PAGINATION_SIZE) {
|
|
await this.handleBatch(batch);
|
|
count += batch.length;
|
|
batch.length = 0;
|
|
}
|
|
}
|
|
|
|
await this.handleBatch(batch);
|
|
count += batch.length;
|
|
batch.length = 0;
|
|
|
|
this.logger.log(`Queued ${count} asset(s) for deletion from the trash`);
|
|
|
|
return JobStatus.Success;
|
|
}
|
|
|
|
private async handleBatch(ids: string[]) {
|
|
this.logger.debug(`Queueing ${ids.length} asset(s) for deletion from the trash`);
|
|
await this.jobRepository.queueAll(
|
|
ids.map((assetId) => ({
|
|
name: JobName.AssetDelete,
|
|
data: {
|
|
id: assetId,
|
|
deleteOnDisk: true,
|
|
},
|
|
})),
|
|
);
|
|
}
|
|
}
|