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:
parent
86f5ceb80e
commit
f0a5d39625
3 changed files with 43 additions and 23 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue