diff --git a/.dockerignore b/.dockerignore index bcb7bef..eb76501 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,5 @@ .next .vscode -public/images node_modules data .env diff --git a/Dockerfile b/Dockerfile index 3f7fa0d..c36dfdc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,7 +39,7 @@ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static RUN mkdir -p data && chown nextjs:nodejs data -RUN mkdir -p public/images && chown nextjs:nodejs public/images +RUN mkdir -p data/images && chown nextjs:nodejs data/images USER nextjs diff --git a/public/images/.gitignore b/public/images/.gitignore deleted file mode 100644 index b90600f..0000000 --- a/public/images/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.jpg -*.png -*.jpeg \ No newline at end of file diff --git a/src/app/api/images/[id]/route.ts b/src/app/api/images/[id]/route.ts index 2b6928e..e88465d 100644 --- a/src/app/api/images/[id]/route.ts +++ b/src/app/api/images/[id]/route.ts @@ -1,6 +1,54 @@ -import { deleteImageById } from '@/lib/data'; +import { imagesDir } from '@/const/api'; +import { deleteImageById, getImageDataById } from '@/lib/data'; import { getSession } from '@/lib/session'; +import fs from 'fs/promises'; import { NextRequest, NextResponse } from 'next/server'; +import path from 'path'; + +export async function GET(request: NextRequest, context: { params: Promise<{ id: string }> }) { + try { + const { id } = await context.params; + const imageData = await getImageDataById(id); + + if (!imageData) { + return NextResponse.json({ error: 'Image not found in data' }, { status: 404 }); + } + + const filePath = path.join(imagesDir, imageData.relative_path); + + try { + await fs.access(filePath); + } catch (error) { + console.error(error); + return NextResponse.json({ error: 'Image not found' }, { status: 404 }); + } + + const imageBuffer = await fs.readFile(filePath); + + const ext = path.extname(id).toLowerCase(); + const mimeTypes: { [key: string]: string } = { + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.png': 'image/png', + '.gif': 'image/gif', + '.webp': 'image/webp', + }; + const contentType = mimeTypes[ext] || 'application/octet-stream'; + + const headers = new Headers(); + headers.set('Content-Type', contentType); + headers.set('Content-Disposition', `attachment; filename="${imageData.relative_path}"`); + + return new NextResponse(new Uint8Array(imageBuffer), { + status: 200, + statusText: 'OK', + headers, + }); + } catch (error) { + console.error(error); + return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 }); + } +} export async function DELETE(request: NextRequest, context: { params: Promise<{ id: string }> }) { const session = await getSession(); diff --git a/src/components/Gallery.tsx b/src/components/Gallery.tsx index 2c8bcd3..9e60fa9 100644 --- a/src/components/Gallery.tsx +++ b/src/components/Gallery.tsx @@ -131,7 +131,7 @@ export default function Gallery({ initialImages }: GalleryProps) { width={image.aspect_ratio > HORIZONTAL_ASPECT_RATIO ? image.width : 700} height={image.aspect_ratio < VERTICAL_ASPECT_RATIO ? image.height : 700} loading="lazy" - src={`/images/${image.relative_path}`} + src={`/api/images/${image.id}`} alt={image.aspect_ratio?.toString()} onClick={() => setFullScreenImage(`/images/${image.relative_path}`)} /> diff --git a/src/components/ImageManager.tsx b/src/components/ImageManager.tsx index 8f2378d..11268bd 100644 --- a/src/components/ImageManager.tsx +++ b/src/components/ImageManager.tsx @@ -117,7 +117,7 @@ export default function ImageManager({ images: initialImages, tags: initialTags {images.map((image) => ( - {image.id} + {image.id} {image.id} diff --git a/src/const/api.ts b/src/const/api.ts index f29d293..b4b55e8 100644 --- a/src/const/api.ts +++ b/src/const/api.ts @@ -1,4 +1,5 @@ -import path from "path"; +import path from 'path'; -export const imagesDir = path.join(process.cwd(), 'public', 'images'); -export const jsonPath = path.join(process.cwd(), 'data', 'images.json'); \ No newline at end of file +const dataDir = path.join(process.cwd(), 'data'); +export const imagesDir = path.join(dataDir, 'images'); +export const jsonPath = path.join(dataDir, 'images.json'); diff --git a/src/lib/data.ts b/src/lib/data.ts index d9d12e8..5ef0d31 100644 --- a/src/lib/data.ts +++ b/src/lib/data.ts @@ -23,6 +23,10 @@ export async function getImageData(): Promise { } } +export async function getImageDataById(id: string): Promise { + return (await getImageData()).find((image) => image.id === id); +} + export function stringToTags(string: string): string[] { return string ? string