Skip to content

Commit 39141d3

Browse files
authored
fix(server): remove offline assets from trash (#12199)
* use port not taken by immich-dev for e2e * remove offline files from trash
1 parent 28bc7f3 commit 39141d3

File tree

4 files changed

+67
-8
lines changed

4 files changed

+67
-8
lines changed

Diff for: e2e/src/api/specs/library.e2e-spec.ts

+53-5
Original file line numberDiff line numberDiff line change
@@ -635,20 +635,21 @@ describe('/libraries', () => {
635635
it('should remove offline files', async () => {
636636
const library = await utils.createLibrary(admin.accessToken, {
637637
ownerId: admin.userId,
638-
importPaths: [`${testAssetDirInternal}/temp/offline2`],
638+
importPaths: [`${testAssetDirInternal}/temp/offline`],
639639
});
640640

641-
utils.createImageFile(`${testAssetDir}/temp/offline2/assetA.png`);
641+
utils.createImageFile(`${testAssetDir}/temp/offline/online.png`);
642+
utils.createImageFile(`${testAssetDir}/temp/offline/offline.png`);
642643

643644
await scan(admin.accessToken, library.id);
644645
await utils.waitForQueueFinish(admin.accessToken, 'library');
645646

646647
const { assets: initialAssets } = await utils.metadataSearch(admin.accessToken, {
647648
libraryId: library.id,
648649
});
649-
expect(initialAssets.count).toBe(1);
650+
expect(initialAssets.count).toBe(2);
650651

651-
utils.removeImageFile(`${testAssetDir}/temp/offline2/assetA.png`);
652+
utils.removeImageFile(`${testAssetDir}/temp/offline/offline.png`);
652653

653654
await scan(admin.accessToken, library.id);
654655
await utils.waitForQueueFinish(admin.accessToken, 'library');
@@ -669,7 +670,54 @@ describe('/libraries', () => {
669670

670671
const { assets } = await utils.metadataSearch(admin.accessToken, { libraryId: library.id });
671672

672-
expect(assets.count).toBe(0);
673+
expect(assets.count).toBe(1);
674+
675+
utils.removeImageFile(`${testAssetDir}/temp/offline/online.png`);
676+
});
677+
678+
it('should remove offline files from trash', async () => {
679+
const library = await utils.createLibrary(admin.accessToken, {
680+
ownerId: admin.userId,
681+
importPaths: [`${testAssetDirInternal}/temp/offline`],
682+
});
683+
684+
utils.createImageFile(`${testAssetDir}/temp/offline/online.png`);
685+
utils.createImageFile(`${testAssetDir}/temp/offline/offline.png`);
686+
687+
await scan(admin.accessToken, library.id);
688+
await utils.waitForQueueFinish(admin.accessToken, 'library');
689+
690+
const { assets: initialAssets } = await utils.metadataSearch(admin.accessToken, {
691+
libraryId: library.id,
692+
});
693+
694+
expect(initialAssets.count).toBe(2);
695+
utils.removeImageFile(`${testAssetDir}/temp/offline/offline.png`);
696+
697+
await scan(admin.accessToken, library.id);
698+
await utils.waitForQueueFinish(admin.accessToken, 'library');
699+
700+
const { assets: offlineAssets } = await utils.metadataSearch(admin.accessToken, {
701+
libraryId: library.id,
702+
isOffline: true,
703+
});
704+
expect(offlineAssets.count).toBe(1);
705+
706+
const { status } = await request(app)
707+
.post(`/libraries/${library.id}/removeOffline`)
708+
.set('Authorization', `Bearer ${admin.accessToken}`)
709+
.send();
710+
expect(status).toBe(204);
711+
await utils.waitForQueueFinish(admin.accessToken, 'library');
712+
await utils.waitForQueueFinish(admin.accessToken, 'backgroundTask');
713+
714+
const { assets } = await utils.metadataSearch(admin.accessToken, { libraryId: library.id });
715+
716+
expect(assets.count).toBe(1);
717+
expect(assets.items[0].isOffline).toBe(false);
718+
expect(assets.items[0].originalPath).toEqual(`${testAssetDirInternal}/temp/offline/online.png`);
719+
720+
utils.removeImageFile(`${testAssetDir}/temp/offline/online.png`);
673721
});
674722

675723
it('should not remove online files', async () => {

Diff for: server/src/interfaces/asset.interface.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,12 @@ export interface IAssetRepository {
169169
order?: FindOptionsOrder<AssetEntity>,
170170
): Promise<AssetEntity | null>;
171171
getWithout(pagination: PaginationOptions, property: WithoutProperty): Paginated<AssetEntity>;
172-
getWith(pagination: PaginationOptions, property: WithProperty, libraryId?: string): Paginated<AssetEntity>;
172+
getWith(
173+
pagination: PaginationOptions,
174+
property: WithProperty,
175+
libraryId?: string,
176+
withDeleted?: boolean,
177+
): Paginated<AssetEntity>;
173178
getRandom(userId: string, count: number): Promise<AssetEntity[]>;
174179
getFirstAssetForAlbumId(albumId: string): Promise<AssetEntity | null>;
175180
getLastUpdatedAssetForAlbumId(albumId: string): Promise<AssetEntity | null>;

Diff for: server/src/repositories/asset.repository.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,12 @@ export class AssetRepository implements IAssetRepository {
527527
});
528528
}
529529

530-
getWith(pagination: PaginationOptions, property: WithProperty, libraryId?: string): Paginated<AssetEntity> {
530+
getWith(
531+
pagination: PaginationOptions,
532+
property: WithProperty,
533+
libraryId?: string,
534+
withDeleted = false,
535+
): Paginated<AssetEntity> {
531536
let where: FindOptionsWhere<AssetEntity> | FindOptionsWhere<AssetEntity>[] = {};
532537

533538
switch (property) {
@@ -557,6 +562,7 @@ export class AssetRepository implements IAssetRepository {
557562

558563
return paginate(this.repository, pagination, {
559564
where,
565+
withDeleted,
560566
order: {
561567
// Ensures correct order when paginating
562568
createdAt: 'ASC',

Diff for: server/src/services/library.service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ export class LibraryService {
581581
this.logger.debug(`Removing offline assets for library ${job.id}`);
582582

583583
const assetPagination = usePagination(JOBS_LIBRARY_PAGINATION_SIZE, (pagination) =>
584-
this.assetRepository.getWith(pagination, WithProperty.IS_OFFLINE, job.id),
584+
this.assetRepository.getWith(pagination, WithProperty.IS_OFFLINE, job.id, true),
585585
);
586586

587587
let offlineAssets = 0;

0 commit comments

Comments
 (0)