pull/27636/merge
aviv926 2026-06-03 08:18:49 -05:00 committed by GitHub
commit bd0486c88c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 15 deletions

View File

@ -543,16 +543,9 @@ describe(AssetService.name, () => {
await sut.handleAssetDeletion({ id: asset.id, deleteOnDisk: true });
expect(mocks.job.queue.mock.calls).toEqual([
[
{
name: JobName.FileDelete,
data: {
files: [...asset.files.map(({ path }) => path), asset.originalPath],
},
},
],
]);
expect(mocks.storage.unlink.mock.calls).toEqual(
[...asset.files.map(({ path }) => path), asset.originalPath].map((file) => [file]),
);
expect(mocks.asset.remove).toHaveBeenCalledWith(getForAssetDeletion(asset));
});
@ -581,8 +574,8 @@ describe(AssetService.name, () => {
expect(mocks.job.queue.mock.calls).toEqual([
[{ name: JobName.AssetDelete, data: { id: motionAsset.id, deleteOnDisk: true } }],
[{ name: JobName.FileDelete, data: { files: [asset.originalPath] } }],
]);
expect(mocks.storage.unlink).toHaveBeenCalledWith(asset.originalPath);
});
it('should not delete a live motion part if it is being used by another asset', async () => {
@ -592,9 +585,8 @@ describe(AssetService.name, () => {
await sut.handleAssetDeletion({ id: asset.id, deleteOnDisk: true });
expect(mocks.job.queue.mock.calls).toEqual([
[{ name: JobName.FileDelete, data: { files: [`/data/library/IMG_${asset.id}.jpg`] } }],
]);
expect(mocks.job.queue.mock.calls).toEqual([]);
expect(mocks.storage.unlink).toHaveBeenCalledWith(`/data/library/IMG_${asset.id}.jpg`);
});
it('should update usage', async () => {

View File

@ -314,6 +314,11 @@ export class AssetService extends BaseService {
return JobStatus.Failed;
}
const fileDeletionStatus = await this.deleteAssetFiles(id, this.getFilesForDeletion(asset, deleteOnDisk));
if (fileDeletionStatus === JobStatus.Failed) {
return JobStatus.Failed;
}
// replace the parent of the stack children with a new asset
if (asset.stack?.primaryAssetId === id) {
// this only includes timeline visible assets and excludes the primary asset
@ -347,6 +352,13 @@ export class AssetService extends BaseService {
}
}
return JobStatus.Success;
}
private getFilesForDeletion(
asset: { files: AssetFile[]; originalPath: string; isOffline: boolean },
deleteOnDisk: boolean,
): string[] {
const assetFiles = getAssetFiles(asset.files ?? []);
const files = [
assetFiles.thumbnailFile?.path,
@ -362,7 +374,18 @@ export class AssetService extends BaseService {
files.push(assetFiles.sidecarFile?.path, asset.originalPath);
}
await this.jobRepository.queue({ name: JobName.FileDelete, data: { files: files.filter(Boolean) } });
return files.filter((file): file is string => file !== undefined);
}
private async deleteAssetFiles(assetId: string, files: string[]): Promise<JobStatus> {
for (const file of files) {
try {
await this.storageRepository.unlink(file);
} catch (error) {
this.logger.warn(`Unable to remove asset file for asset ${assetId}: ${file}`, error);
return JobStatus.Failed;
}
}
return JobStatus.Success;
}