1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-01-01 08:31:59 +00:00

chore(server): return duplicate assets as group (#9576)

* chore(server): return duplicate assets as group

* file name
This commit is contained in:
Alex 2024-05-18 13:15:56 -05:00 committed by GitHub
parent 9aed736911
commit 60427f18ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 28 additions and 5 deletions

View file

@ -1,7 +1,7 @@
import { Controller, Get } from '@nestjs/common'; import { Controller, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger'; import { ApiTags } from '@nestjs/swagger';
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
import { AuthDto } from 'src/dtos/auth.dto'; import { AuthDto } from 'src/dtos/auth.dto';
import { DuplicateResponseDto } from 'src/dtos/duplicate.dto';
import { Auth, Authenticated } from 'src/middleware/auth.guard'; import { Auth, Authenticated } from 'src/middleware/auth.guard';
import { DuplicateService } from 'src/services/duplicate.service'; import { DuplicateService } from 'src/services/duplicate.service';
@ -12,7 +12,7 @@ export class DuplicateController {
@Get() @Get()
@Authenticated() @Authenticated()
getAssetDuplicates(@Auth() auth: AuthDto): Promise<AssetResponseDto[]> { getAssetDuplicates(@Auth() auth: AuthDto): Promise<DuplicateResponseDto[]> {
return this.service.getDuplicates(auth); return this.service.getDuplicates(auth);
} }
} }

View file

@ -50,6 +50,7 @@ export class AssetResponseDto extends SanitizedAssetResponseDto {
stack?: AssetResponseDto[]; stack?: AssetResponseDto[];
@ApiProperty({ type: 'integer' }) @ApiProperty({ type: 'integer' })
stackCount!: number | null; stackCount!: number | null;
duplicateId?: string | null;
} }
export type AssetMapOptions = { export type AssetMapOptions = {
@ -130,6 +131,7 @@ export function mapAsset(entity: AssetEntity, options: AssetMapOptions = {}): As
isExternal: false, isExternal: false,
isReadOnly: false, isReadOnly: false,
hasMetadata: true, hasMetadata: true,
duplicateId: entity.duplicateId,
}; };
} }

View file

@ -0,0 +1,19 @@
import { groupBy } from 'lodash';
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
export class DuplicateResponseDto {
duplicateId!: string;
assets!: AssetResponseDto[];
}
export function mapDuplicateResponse(assets: AssetResponseDto[]): DuplicateResponseDto[] {
const result = [];
const grouped = groupBy(assets, (a) => a.duplicateId);
for (const [duplicateId, assets] of Object.entries(grouped)) {
result.push({ duplicateId, assets });
}
return result;
}

View file

@ -1,7 +1,8 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { SystemConfigCore } from 'src/cores/system-config.core'; import { SystemConfigCore } from 'src/cores/system-config.core';
import { AssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto'; import { mapAsset } from 'src/dtos/asset-response.dto';
import { AuthDto } from 'src/dtos/auth.dto'; import { AuthDto } from 'src/dtos/auth.dto';
import { DuplicateResponseDto, mapDuplicateResponse } from 'src/dtos/duplicate.dto';
import { AssetEntity } from 'src/entities/asset.entity'; import { AssetEntity } from 'src/entities/asset.entity';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.interface'; import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.interface';
import { ICryptoRepository } from 'src/interfaces/crypto.interface'; import { ICryptoRepository } from 'src/interfaces/crypto.interface';
@ -35,9 +36,10 @@ export class DuplicateService {
this.configCore = SystemConfigCore.create(systemMetadataRepository, logger); this.configCore = SystemConfigCore.create(systemMetadataRepository, logger);
} }
async getDuplicates(auth: AuthDto): Promise<AssetResponseDto[]> { async getDuplicates(auth: AuthDto): Promise<DuplicateResponseDto[]> {
const res = await this.assetRepository.getDuplicates({ userIds: [auth.user.id] }); const res = await this.assetRepository.getDuplicates({ userIds: [auth.user.id] });
return res.map((a) => mapAsset(a, { auth }));
return mapDuplicateResponse(res.map((a) => mapAsset(a, { auth })));
} }
async handleQueueSearchDuplicates({ force }: IBaseJob): Promise<JobStatus> { async handleQueueSearchDuplicates({ force }: IBaseJob): Promise<JobStatus> {