From 43abb6d5fd0202714b24ce674cb70194d45a6156 Mon Sep 17 00:00:00 2001 From: theoleuthardt Date: Sun, 16 Feb 2025 17:52:08 +0100 Subject: [PATCH] feat: extended backend functionality for converting files to the selected file extension sent to the backend via api --- backend/server.ts | 2 +- backend/src/routes/libreconvert.route.ts | 57 +++++++++++++++++++----- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/backend/server.ts b/backend/server.ts index 03bb2e9..5156540 100644 --- a/backend/server.ts +++ b/backend/server.ts @@ -5,7 +5,7 @@ import { libreConvert } from "./src/routes/libreconvert.route"; const app = Fastify({ logger: true }); -app.register(cors, { origin: "*" }); +app.register(cors, { origin: "*", exposedHeaders: 'Content-Disposition' }); app.register(multipart); app.register(libreConvert); diff --git a/backend/src/routes/libreconvert.route.ts b/backend/src/routes/libreconvert.route.ts index ac4c8af..746be93 100644 --- a/backend/src/routes/libreconvert.route.ts +++ b/backend/src/routes/libreconvert.route.ts @@ -1,30 +1,65 @@ import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify"; import * as libre from "libreoffice-convert"; import { promisify } from "util"; +import { MultipartValue } from "@fastify/multipart"; const libreConvertAsync = promisify(libre.convert); +const mimeTypes: { [key: string]: string } = { + 'pdf': 'application/pdf', + 'html': 'text/html', + 'doc': 'application/msword', + 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'txt': 'text/plain', + 'rtf': 'application/rtf', + 'odt': 'application/vnd.oasis.opendocument.text', + 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xls': 'application/vnd.ms-excel', + 'ods': 'application/vnd.oasis.opendocument.spreadsheet', + 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'ppt': 'application/vnd.ms-powerpoint', + 'odp': 'application/vnd.oasis.opendocument.presentation' +}; + export async function libreConvert(app: FastifyInstance) { app.post("/api/libre-convert", async (request: FastifyRequest, reply: FastifyReply) => { try { - const data = await request.file(); - if (!data) { - return reply.status(400).send({ error: "No file uploaded!" }); + const parts = request.parts(); + + let fileBuffer: Buffer | null = null; + let outputFileExt = ""; + + for await (const part of parts) { + if (part.type === "file") { + fileBuffer = await part.toBuffer(); + } else if (part.fieldname === "outputFormat" && part.type === "field") { + outputFileExt = (part as MultipartValue).value; + console.log("Output format:", outputFileExt); + } } - const ext = ".pdf"; - const format = ext.substring(1); - const fileBuffer = await data.toBuffer(); + if (!fileBuffer) { + return reply.status(400).send({ error: "No file uploaded!" }); + } + if (!outputFileExt) { + return reply.status(400).send({ error: "No output format provided!" }); + } + if (!outputFileExt.startsWith(".")) { + outputFileExt = "." + outputFileExt; + } - const pdfBuffer = await libreConvertAsync(fileBuffer, ext, undefined); + const format = outputFileExt.substring(1); + const mimeType = mimeTypes[format] || 'application/octet-stream'; + + const convertedBuffer = await libreConvertAsync(fileBuffer, outputFileExt, undefined); reply - .header("Content-Type", "application/" + format) - .header("Content-Disposition", "attachment; filename=converted" + ext) - .send(pdfBuffer); + .header("Content-Type", mimeType) + .header("Content-Disposition", `attachment; filename="converted${outputFileExt}"`) + .send(convertedBuffer); } catch (error) { console.error("Convert error:", error); reply.status(500).send({ error: "Error while converting!" }); } }); -} +} \ No newline at end of file