60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import db from "@/db";
|
|
import fs from "fs";
|
|
import path from "path";
|
|
|
|
export async function GET(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ id: string }> }
|
|
) {
|
|
const { id } = await params;
|
|
try {
|
|
const photoId = parseInt(id);
|
|
|
|
if (isNaN(photoId)) {
|
|
return NextResponse.json({ error: "Invalid photo ID" }, { status: 400 });
|
|
}
|
|
|
|
const photo = db.prepare("SELECT * FROM media WHERE id = ? AND type = 'photo'").get(photoId) as { path: string, title: string } | undefined;
|
|
|
|
if (!photo) {
|
|
return NextResponse.json({ error: "Photo not found" }, { status: 404 });
|
|
}
|
|
|
|
const photoPath = photo.path;
|
|
|
|
if (!fs.existsSync(photoPath)) {
|
|
return NextResponse.json({ error: "Photo file not found" }, { status: 404 });
|
|
}
|
|
|
|
const stat = fs.statSync(photoPath);
|
|
const fileSize = stat.size;
|
|
const ext = path.extname(photoPath).toLowerCase();
|
|
|
|
// Determine content type based on file extension
|
|
let contentType = 'image/jpeg'; // default
|
|
if (ext === '.png') contentType = 'image/png';
|
|
else if (ext === '.gif') contentType = 'image/gif';
|
|
else if (ext === '.webp') contentType = 'image/webp';
|
|
else if (ext === '.bmp') contentType = 'image/bmp';
|
|
else if (ext === '.tiff' || ext === '.tif') contentType = 'image/tiff';
|
|
else if (ext === '.svg') contentType = 'image/svg+xml';
|
|
|
|
const headers = new Headers({
|
|
"Content-Length": fileSize.toString(),
|
|
"Content-Type": contentType,
|
|
"Cache-Control": "public, max-age=31536000", // Cache for 1 year
|
|
});
|
|
|
|
const file = fs.createReadStream(photoPath);
|
|
|
|
return new Response(file as any, {
|
|
status: 200,
|
|
headers,
|
|
});
|
|
} catch (error) {
|
|
console.error("Error serving photo:", error);
|
|
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
|
|
}
|
|
}
|