feat(server): return asset checksum (#2582)

* feat: return asset checksum

* chore: generate open api

* chore: coverage

* feat(server): support base64 hashes in bulk upload check:

* chore: generate open api
This commit is contained in:
Jason Rasmussen
2023-05-27 21:56:17 -04:00
committed by GitHub
parent 7f0ad8e2d2
commit bca4626708
17 changed files with 111 additions and 103 deletions

View File

@@ -1,6 +1,6 @@
import { AlbumEntity, AssetEntity, UserEntity } from '@app/infra/entities';
import { BadRequestException, ForbiddenException, Inject, Injectable } from '@nestjs/common';
import { IAssetRepository } from '../asset';
import { IAssetRepository, mapAsset } from '../asset';
import { AuthUserDto } from '../auth';
import { IJobRepository, JobName } from '../job';
import { IAlbumRepository } from './album.repository';
@@ -40,6 +40,7 @@ export class AlbumService {
return albums.map((album) => {
return {
...album,
assets: album?.assets?.map(mapAsset),
sharedLinks: undefined, // Don't return shared links
shared: album.sharedLinks?.length > 0 || album.sharedUsers?.length > 0,
assetCount: albumsAssetCountObj[album.id],

View File

@@ -15,7 +15,7 @@ export class AssetResponseDto {
type!: AssetType;
originalPath!: string;
originalFileName!: string;
resizePath!: string | null;
resized!: boolean;
fileCreatedAt!: string;
fileModifiedAt!: string;
updatedAt!: string;
@@ -23,13 +23,13 @@ export class AssetResponseDto {
isArchived!: boolean;
mimeType!: string | null;
duration!: string;
webpPath!: string | null;
encodedVideoPath?: string | null;
exifInfo?: ExifResponseDto;
smartInfo?: SmartInfoResponseDto;
livePhotoVideoId?: string | null;
tags?: TagResponseDto[];
people?: PersonResponseDto[];
/**base64 encoded sha1 hash */
checksum!: string;
}
export function mapAsset(entity: AssetEntity): AssetResponseDto {
@@ -41,21 +41,20 @@ export function mapAsset(entity: AssetEntity): AssetResponseDto {
type: entity.type,
originalPath: entity.originalPath,
originalFileName: entity.originalFileName,
resizePath: entity.resizePath,
resized: !!entity.resizePath,
fileCreatedAt: entity.fileCreatedAt,
fileModifiedAt: entity.fileModifiedAt,
updatedAt: entity.updatedAt,
isFavorite: entity.isFavorite,
isArchived: entity.isArchived,
mimeType: entity.mimeType,
webpPath: entity.webpPath,
encodedVideoPath: entity.encodedVideoPath,
duration: entity.duration ?? '0:00:00.00000',
exifInfo: entity.exifInfo ? mapExif(entity.exifInfo) : undefined,
smartInfo: entity.smartInfo ? mapSmartInfo(entity.smartInfo) : undefined,
livePhotoVideoId: entity.livePhotoVideoId,
tags: entity.tags?.map(mapTag),
people: entity.faces?.map(mapFace),
checksum: entity.checksum.toString('base64'),
};
}
@@ -68,20 +67,19 @@ export function mapAssetWithoutExif(entity: AssetEntity): AssetResponseDto {
type: entity.type,
originalPath: entity.originalPath,
originalFileName: entity.originalFileName,
resizePath: entity.resizePath,
resized: !!entity.resizePath,
fileCreatedAt: entity.fileCreatedAt,
fileModifiedAt: entity.fileModifiedAt,
updatedAt: entity.updatedAt,
isFavorite: entity.isFavorite,
isArchived: entity.isArchived,
mimeType: entity.mimeType,
webpPath: entity.webpPath,
encodedVideoPath: entity.encodedVideoPath,
duration: entity.duration ?? '0:00:00.00000',
exifInfo: undefined,
smartInfo: entity.smartInfo ? mapSmartInfo(entity.smartInfo) : undefined,
livePhotoVideoId: entity.livePhotoVideoId,
tags: entity.tags?.map(mapTag),
people: entity.faces?.map(mapFace),
checksum: entity.checksum.toString('base64'),
};
}

View File

@@ -3,7 +3,7 @@ import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common'
import { ConfigService } from '@nestjs/config';
import { mapAlbum } from '../album';
import { IAlbumRepository } from '../album/album.repository';
import { mapAsset } from '../asset';
import { AssetResponseDto, mapAsset } from '../asset';
import { IAssetRepository } from '../asset/asset.repository';
import { AuthUserDto } from '../auth';
import { MACHINE_LEARNING_ENABLED } from '../domain.constant';
@@ -103,9 +103,13 @@ export class SearchService {
}
}
async getExploreData(authUser: AuthUserDto): Promise<SearchExploreItem<AssetEntity>[]> {
async getExploreData(authUser: AuthUserDto): Promise<SearchExploreItem<AssetResponseDto>[]> {
this.assertEnabled();
return this.searchRepository.explore(authUser.id);
const results = await this.searchRepository.explore(authUser.id);
return results.map(({ fieldName, items }) => ({
fieldName,
items: items.map(({ value, data }) => ({ value, data: mapAsset(data) })),
}));
}
async search(authUser: AuthUserDto, dto: SearchDto): Promise<SearchResponseDto> {

View File

@@ -446,7 +446,7 @@ const assetResponse: AssetResponseDto = {
type: AssetType.VIDEO,
originalPath: 'fake_path/jpeg',
originalFileName: 'asset_1.jpeg',
resizePath: '',
resized: false,
fileModifiedAt: today.toISOString(),
fileCreatedAt: today.toISOString(),
updatedAt: today.toISOString(),
@@ -457,13 +457,12 @@ const assetResponse: AssetResponseDto = {
tags: [],
objects: ['a', 'b', 'c'],
},
webpPath: '',
encodedVideoPath: '',
duration: '0:00:00.00000',
exifInfo: assetInfo,
livePhotoVideoId: null,
tags: [],
people: [],
checksum: 'ZmlsZSBoYXNo',
};
const albumResponse: AlbumResponseDto = {