From 4eb7758f56089481a7319a0a0fc2853a013dc2ea Mon Sep 17 00:00:00 2001 From: Eli Gao Date: Mon, 2 Dec 2024 03:21:08 +0800 Subject: [PATCH] feat(server): specify names for thumbnail files (#14425) --- server/src/services/asset-media.service.spec.ts | 3 +++ server/src/services/asset-media.service.ts | 6 +++++- server/src/utils/file.ts | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/server/src/services/asset-media.service.spec.ts b/server/src/services/asset-media.service.spec.ts index d68140367d..da7e23be54 100644 --- a/server/src/services/asset-media.service.spec.ts +++ b/server/src/services/asset-media.service.spec.ts @@ -571,6 +571,7 @@ describe(AssetMediaService.name, () => { path: '/path/to/preview.jpg', cacheControl: CacheControl.PRIVATE_WITH_CACHE, contentType: 'image/jpeg', + fileName: 'asset-id_thumbnail.jpg', }), ); }); @@ -585,6 +586,7 @@ describe(AssetMediaService.name, () => { path: assetStub.image.files[0].path, cacheControl: CacheControl.PRIVATE_WITH_CACHE, contentType: 'image/jpeg', + fileName: 'asset-id_preview.jpg', }), ); }); @@ -599,6 +601,7 @@ describe(AssetMediaService.name, () => { path: assetStub.image.files[1].path, cacheControl: CacheControl.PRIVATE_WITH_CACHE, contentType: 'application/octet-stream', + fileName: 'asset-id_thumbnail.ext', }), ); }); diff --git a/server/src/services/asset-media.service.ts b/server/src/services/asset-media.service.ts index 2424c93e44..e96d1fd0a6 100644 --- a/server/src/services/asset-media.service.ts +++ b/server/src/services/asset-media.service.ts @@ -27,7 +27,7 @@ import { AuthRequest } from 'src/middleware/auth.guard'; import { BaseService } from 'src/services/base.service'; import { requireUploadAccess } from 'src/utils/access'; import { asRequest, getAssetFiles, onBeforeLink } from 'src/utils/asset.util'; -import { ImmichFileResponse } from 'src/utils/file'; +import { getFilenameExtension, getFileNameWithoutExtension, ImmichFileResponse } from 'src/utils/file'; import { mimeTypes } from 'src/utils/mime-types'; import { fromChecksum } from 'src/utils/request'; import { QueryFailedError } from 'typeorm'; @@ -217,8 +217,12 @@ export class AssetMediaService extends BaseService { if (!filepath) { throw new NotFoundException('Asset media not found'); } + let fileName = getFileNameWithoutExtension(asset.originalFileName); + fileName += `_${size}`; + fileName += getFilenameExtension(filepath); return new ImmichFileResponse({ + fileName, path: filepath, contentType: mimeTypes.lookup(filepath), cacheControl: CacheControl.PRIVATE_WITH_CACHE, diff --git a/server/src/utils/file.ts b/server/src/utils/file.ts index 3b26c3e1ba..ba487840e5 100644 --- a/server/src/utils/file.ts +++ b/server/src/utils/file.ts @@ -24,6 +24,7 @@ export class ImmichFileResponse { public readonly path!: string; public readonly contentType!: string; public readonly cacheControl!: CacheControl; + public readonly fileName?: string; constructor(response: ImmichFileResponse) { Object.assign(this, response); @@ -56,6 +57,9 @@ export const sendFile = async ( } res.header('Content-Type', file.contentType); + if (file.fileName) { + res.header('Content-Disposition', `inline; filename="${file.fileName}"`); + } const options: SendFileOptions = { dotfiles: 'allow' }; if (!isAbsolute(file.path)) {