feat: image optimisation
This commit is contained in:
@@ -2,24 +2,80 @@ import { client } from "$lib/server/nextcloud";
|
||||
import { error } from "@sveltejs/kit";
|
||||
import type { RequestHandler } from "./$types";
|
||||
import mime from "mime-types";
|
||||
import { env } from "$env/dynamic/private";
|
||||
|
||||
export const GET: RequestHandler = async ({ params }) => {
|
||||
export const GET: RequestHandler = async ({ params, url }) => {
|
||||
const { path } = params;
|
||||
const width = url.searchParams.get("w");
|
||||
const height = url.searchParams.get("h");
|
||||
|
||||
if (!path) {
|
||||
throw error(400, "Path is required");
|
||||
}
|
||||
|
||||
try {
|
||||
// Fetch from Nextcloud. We assume the path is relative to the root or a specific folder.
|
||||
// If your files are in a specific folder, e.g., "Schreifuchs", prepend it here.
|
||||
const buffer = await client.getFileContents("/" + path);
|
||||
const contentType = mime.lookup(path) || "application/octet-stream";
|
||||
let buffer: ArrayBuffer;
|
||||
let contentType: string;
|
||||
|
||||
if (width || height) {
|
||||
// Use Nextcloud Preview API
|
||||
const baseUrl = env.NEXTCLOUD_URL?.endsWith("/") ? env.NEXTCLOUD_URL : `${env.NEXTCLOUD_URL}/`;
|
||||
|
||||
let fullPath = path;
|
||||
if (env.NEXTCLOUD_BASE_DIR) {
|
||||
const baseDir = env.NEXTCLOUD_BASE_DIR.replace(/^\/+|\/+$/g, "");
|
||||
fullPath = baseDir ? `${baseDir}/${path}` : path;
|
||||
}
|
||||
|
||||
const previewUrl = new URL(`${baseUrl}index.php/core/preview`);
|
||||
// Ensure leading slash for the file parameter
|
||||
const fileParam = fullPath.startsWith('/') ? fullPath : `/${fullPath}`;
|
||||
previewUrl.searchParams.set("file", fileParam);
|
||||
if (width) previewUrl.searchParams.set("x", width);
|
||||
if (height) previewUrl.searchParams.set("y", height);
|
||||
previewUrl.searchParams.set("forceIcon", "0");
|
||||
|
||||
const auth = Buffer.from(`${env.NEXTCLOUD_USER}:${env.NEXTCLOUD_PASSWORD}`).toString("base64");
|
||||
|
||||
console.log(`Fetching preview: ${previewUrl.toString()} for file: ${fullPath}`);
|
||||
|
||||
try {
|
||||
const response = await fetch(previewUrl.toString(), {
|
||||
headers: {
|
||||
"Authorization": `Basic ${auth}`
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
buffer = await response.arrayBuffer();
|
||||
contentType = response.headers.get("Content-Type") || "image/png";
|
||||
|
||||
return new Response(buffer, {
|
||||
headers: {
|
||||
"Content-Type": contentType,
|
||||
"Cache-Control": "public, max-age=86400",
|
||||
"Vary": "Accept-Encoding"
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn(`Nextcloud preview failed (${response.status} ${response.statusText}) for ${fullPath}. Falling back to original.`);
|
||||
}
|
||||
} catch (fetchError) {
|
||||
console.error(`Fetch error during preview request for ${fullPath}:`, fetchError);
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch original via WebDAV (Fallback or no resize requested)
|
||||
console.log(`Fetching original file via WebDAV: /${path}`);
|
||||
const data = await client.getFileContents("/" + path);
|
||||
buffer = data as ArrayBuffer;
|
||||
contentType = mime.lookup(path) || "application/octet-stream";
|
||||
|
||||
return new Response(buffer as any, {
|
||||
return new Response(buffer, {
|
||||
headers: {
|
||||
"Content-Type": contentType,
|
||||
"Cache-Control": "public, max-age=3600" // Cache for 1 hour
|
||||
"Cache-Control": "public, max-age=86400",
|
||||
"Vary": "Accept-Encoding"
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user