0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-01-07 00:50:23 -05:00

fix: live photo uploads (#4167)

* fix: live photo uploads

* fix: format

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
Jason Rasmussen 2023-09-21 21:35:25 -04:00 committed by GitHub
parent 86f5ceb80e
commit f0a5d39625
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 23 deletions

View file

@ -19,11 +19,14 @@ export interface AssetOwnerCheck extends AssetCheck {
ownerId: string; ownerId: string;
} }
export type AssetCreate = Omit<
AssetEntity,
'id' | 'createdAt' | 'updatedAt' | 'owner' | 'livePhotoVideoId' | 'library'
>;
export interface IAssetRepository { export interface IAssetRepository {
get(id: string): Promise<AssetEntity | null>; get(id: string): Promise<AssetEntity | null>;
create( create(asset: AssetCreate): Promise<AssetEntity>;
asset: Omit<AssetEntity, 'id' | 'createdAt' | 'updatedAt' | 'ownerId' | 'libraryId' | 'livePhotoVideoId'>,
): Promise<AssetEntity>;
remove(asset: AssetEntity): Promise<void>; remove(asset: AssetEntity): Promise<void>;
getAllByUserId(userId: string, dto: AssetSearchDto): Promise<AssetEntity[]>; getAllByUserId(userId: string, dto: AssetSearchDto): Promise<AssetEntity[]>;
getAllByDeviceId(userId: string, deviceId: string): Promise<string[]>; getAllByDeviceId(userId: string, deviceId: string): Promise<string[]>;
@ -151,9 +154,7 @@ export class AssetRepository implements IAssetRepository {
}); });
} }
create( create(asset: AssetCreate): Promise<AssetEntity> {
asset: Omit<AssetEntity, 'id' | 'createdAt' | 'updatedAt' | 'ownerId' | 'livePhotoVideoId'>,
): Promise<AssetEntity> {
return this.assetRepository.save(asset); return this.assetRepository.save(asset);
} }

View file

@ -1,5 +1,5 @@
import { AuthUserDto, IJobRepository, JobName, mimeTypes, UploadFile } from '@app/domain'; import { AuthUserDto, IJobRepository, JobName, mimeTypes, UploadFile } from '@app/domain';
import { AssetEntity, LibraryEntity, UserEntity } from '@app/infra/entities'; import { AssetEntity } from '@app/infra/entities';
import { parse } from 'node:path'; import { parse } from 'node:path';
import { IAssetRepository } from './asset-repository'; import { IAssetRepository } from './asset-repository';
import { CreateAssetDto, ImportAssetDto } from './dto/create-asset.dto'; import { CreateAssetDto, ImportAssetDto } from './dto/create-asset.dto';
@ -12,14 +12,14 @@ export class AssetCore {
async create( async create(
authUser: AuthUserDto, authUser: AuthUserDto,
dto: CreateAssetDto | ImportAssetDto, dto: (CreateAssetDto | ImportAssetDto) & { libraryId: string },
file: UploadFile, file: UploadFile,
livePhotoAssetId?: string, livePhotoAssetId?: string,
sidecarPath?: string, sidecarPath?: string,
): Promise<AssetEntity> { ): Promise<AssetEntity> {
const asset = await this.repository.create({ const asset = await this.repository.create({
owner: { id: authUser.id } as UserEntity, ownerId: authUser.id,
library: { id: dto.libraryId } as LibraryEntity, libraryId: dto.libraryId,
checksum: file.checksum, checksum: file.checksum,
originalPath: file.originalPath, originalPath: file.originalPath,

View file

@ -90,22 +90,19 @@ export class AssetService {
let livePhotoAsset: AssetEntity | null = null; let livePhotoAsset: AssetEntity | null = null;
try { try {
const libraryId = await this.getLibraryId(authUser, dto.libraryId);
if (livePhotoFile) { if (livePhotoFile) {
const livePhotoDto = { ...dto, assetType: AssetType.VIDEO, isVisible: false }; const livePhotoDto = { ...dto, assetType: AssetType.VIDEO, isVisible: false, libraryId };
livePhotoAsset = await this.assetCore.create(authUser, livePhotoDto, livePhotoFile); livePhotoAsset = await this.assetCore.create(authUser, livePhotoDto, livePhotoFile);
} }
if (!dto.libraryId) { const asset = await this.assetCore.create(
// No library given, fall back to default upload library authUser,
const defaultUploadLibrary = await this.libraryRepository.getDefaultUploadLibrary(authUser.id); { ...dto, libraryId },
file,
if (!defaultUploadLibrary) { livePhotoAsset?.id,
throw new InternalServerErrorException('Cannot find default upload library for user ' + authUser.id); sidecarFile?.originalPath,
} );
dto.libraryId = defaultUploadLibrary.id;
}
const asset = await this.assetCore.create(authUser, dto, file, livePhotoAsset?.id, sidecarFile?.originalPath);
return { id: asset.id, duplicate: false }; return { id: asset.id, duplicate: false };
} catch (error: any) { } catch (error: any) {
@ -164,7 +161,8 @@ export class AssetService {
}; };
try { try {
const asset = await this.assetCore.create(authUser, dto, assetFile, undefined, dto.sidecarPath); const libraryId = await this.getLibraryId(authUser, dto.libraryId);
const asset = await this.assetCore.create(authUser, { ...dto, libraryId }, assetFile, undefined, dto.sidecarPath);
return { id: asset.id, duplicate: false }; return { id: asset.id, duplicate: false };
} catch (error: QueryFailedError | Error | any) { } catch (error: QueryFailedError | Error | any) {
// handle duplicates with a success response // handle duplicates with a success response
@ -505,4 +503,25 @@ export class AssetService {
} }
}); });
} }
private async getLibraryId(authUser: AuthUserDto, libraryId?: string) {
if (libraryId) {
return libraryId;
}
let library = await this.libraryRepository.getDefaultUploadLibrary(authUser.id);
if (!library) {
library = await this.libraryRepository.create({
ownerId: authUser.id,
name: 'Default Library',
assets: [],
type: LibraryType.UPLOAD,
importPaths: [],
exclusionPatterns: [],
isVisible: true,
});
}
return library.id;
}
} }