mirror of
https://github.com/immich-app/immich.git
synced 2025-12-26 01:11:47 +03:00
fix(server): external library motion photo video asset handling (#8721)
* added "isExternal" to the getLibraryAssetPaths query * handleQueueAssetRefresh skip "non external" video asset, closes #8562 * correctly implements live photo deletion for external library * use "external asset" for external library tests * minor: external library asset checksum is "path hash" not file hash * renamed to getExternalLibraryAssetPaths and added isExternal where clause * generated sql * reverted leftover change
This commit is contained in:
@@ -396,7 +396,10 @@ export class AssetService {
|
||||
|
||||
// TODO refactor this to use cascades
|
||||
if (asset.livePhotoVideoId) {
|
||||
await this.jobRepository.queue({ name: JobName.ASSET_DELETION, data: { id: asset.livePhotoVideoId } });
|
||||
await this.jobRepository.queue({
|
||||
name: JobName.ASSET_DELETION,
|
||||
data: { id: asset.livePhotoVideoId, fromExternal },
|
||||
});
|
||||
}
|
||||
|
||||
const files = [asset.thumbnailPath, asset.previewPath, asset.encodedVideoPath];
|
||||
|
||||
@@ -160,7 +160,7 @@ describe(LibraryService.name, () => {
|
||||
storageMock.walk.mockImplementation(async function* generator() {
|
||||
yield '/data/user1/photo.jpg';
|
||||
});
|
||||
assetMock.getLibraryAssetPaths.mockResolvedValue({ items: [], hasNextPage: false });
|
||||
assetMock.getExternalLibraryAssetPaths.mockResolvedValue({ items: [], hasNextPage: false });
|
||||
|
||||
await sut.handleQueueAssetRefresh(mockLibraryJob);
|
||||
|
||||
@@ -189,7 +189,7 @@ describe(LibraryService.name, () => {
|
||||
storageMock.walk.mockImplementation(async function* generator() {
|
||||
yield '/data/user1/photo.jpg';
|
||||
});
|
||||
assetMock.getLibraryAssetPaths.mockResolvedValue({ items: [], hasNextPage: false });
|
||||
assetMock.getExternalLibraryAssetPaths.mockResolvedValue({ items: [], hasNextPage: false });
|
||||
|
||||
await sut.handleQueueAssetRefresh(mockLibraryJob);
|
||||
|
||||
@@ -238,7 +238,7 @@ describe(LibraryService.name, () => {
|
||||
};
|
||||
|
||||
libraryMock.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
|
||||
assetMock.getLibraryAssetPaths.mockResolvedValue({ items: [], hasNextPage: false });
|
||||
assetMock.getExternalLibraryAssetPaths.mockResolvedValue({ items: [], hasNextPage: false });
|
||||
|
||||
await sut.handleQueueAssetRefresh(mockLibraryJob);
|
||||
|
||||
@@ -256,8 +256,8 @@ describe(LibraryService.name, () => {
|
||||
};
|
||||
|
||||
libraryMock.get.mockResolvedValue(libraryStub.externalLibrary1);
|
||||
assetMock.getLibraryAssetPaths.mockResolvedValue({
|
||||
items: [assetStub.image],
|
||||
assetMock.getExternalLibraryAssetPaths.mockResolvedValue({
|
||||
items: [assetStub.external],
|
||||
hasNextPage: false,
|
||||
});
|
||||
|
||||
@@ -278,16 +278,16 @@ describe(LibraryService.name, () => {
|
||||
libraryMock.get.mockResolvedValue(libraryStub.externalLibrary1);
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
storageMock.walk.mockImplementation(async function* generator() {
|
||||
yield assetStub.offline.originalPath;
|
||||
yield assetStub.externalOffline.originalPath;
|
||||
});
|
||||
assetMock.getLibraryAssetPaths.mockResolvedValue({
|
||||
items: [assetStub.offline],
|
||||
assetMock.getExternalLibraryAssetPaths.mockResolvedValue({
|
||||
items: [assetStub.externalOffline],
|
||||
hasNextPage: false,
|
||||
});
|
||||
|
||||
await sut.handleQueueAssetRefresh(mockLibraryJob);
|
||||
|
||||
expect(assetMock.updateAll).toHaveBeenCalledWith([assetStub.offline.id], { isOffline: false });
|
||||
expect(assetMock.updateAll).toHaveBeenCalledWith([assetStub.externalOffline.id], { isOffline: false });
|
||||
expect(assetMock.updateAll).not.toHaveBeenCalledWith(expect.anything(), { isOffline: true });
|
||||
expect(jobMock.queueAll).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -616,7 +616,7 @@ export class LibraryService extends EventEmitter {
|
||||
const assetIdsToMarkOffline = [];
|
||||
const assetIdsToMarkOnline = [];
|
||||
const pagination = usePagination(LIBRARY_SCAN_BATCH_SIZE, (pagination) =>
|
||||
this.assetRepository.getLibraryAssetPaths(pagination, library.id),
|
||||
this.assetRepository.getExternalLibraryAssetPaths(pagination, library.id),
|
||||
);
|
||||
|
||||
this.logger.verbose(`Crawled asset paths paginated`);
|
||||
|
||||
Reference in New Issue
Block a user