Changed PdfFile.filename to exclude file extensions. Other naming fixes
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
|
||||
import Operations from '../../utils/pdf-operations';
|
||||
import { respondWithPdfFile, response_mustHaveExactlyOneFile } from '../../utils/endpoint-utils';
|
||||
import { respondWithPdfFile, respondWithPdfFiles, response_mustHaveExactlyOneFile } from '../../utils/endpoint-utils';
|
||||
import { PdfFile, PdfFileSchema } from '@stirling-pdf/shared-operations/src/wrappers/PdfFile'
|
||||
|
||||
import express, { Request, Response, RequestHandler } from 'express';
|
||||
const router = express.Router();
|
||||
import multer from 'multer';
|
||||
const upload = multer();
|
||||
import Joi, { array } from 'joi';
|
||||
import Joi from 'joi';
|
||||
|
||||
function registerEndpoint(endpoint: string,
|
||||
nameToAppend: string,
|
||||
@@ -37,32 +37,34 @@ function registerEndpoint(endpoint: string,
|
||||
}
|
||||
|
||||
const processed = await operationFunction(value)
|
||||
if (Array.isArray(processed)) {
|
||||
// TODO zip multiple files
|
||||
} else {
|
||||
processed.filename = appendToFilename(processed.filename, nameToAppend);
|
||||
|
||||
if (body.files && Array.isArray(processed)) { // MIMO
|
||||
respondWithPdfFiles(res, processed, nameToAppend);
|
||||
} else if (body.file && Array.isArray(processed)) { // SIMO
|
||||
respondWithPdfFiles(res, processed, body.file.filename + nameToAppend);
|
||||
} else if (body.files && !Array.isArray(processed)) { // MISO
|
||||
respondWithPdfFile(res, processed);
|
||||
} else if (body.file && !Array.isArray(processed)) { // SISO
|
||||
respondWithPdfFile(res, processed);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* appends a string before the last '.' of the given filename
|
||||
*/
|
||||
function appendToFilename(filename: string, str: string) {
|
||||
return filename.replace(/(\.[^.]+)$/, str+'$1')
|
||||
}
|
||||
|
||||
registerEndpoint("/merge-pdfs", "_merged", upload.single("file"), Operations.mergePDFs, Joi.object({
|
||||
registerEndpoint("/merge-pdfs", "", upload.any(), Operations.mergePDFs, Joi.object({
|
||||
files: Joi.array().items(PdfFileSchema).required(),
|
||||
}).required())
|
||||
}).required());
|
||||
|
||||
registerEndpoint("/rotate-pdf", "_rotated", upload.single("file"), Operations.rotatePages, Joi.object({
|
||||
registerEndpoint("/split-pdf", "_split", upload.single("file"), Operations.splitPDF, Joi.object({
|
||||
file: PdfFileSchema.required(),
|
||||
pageNumbers: Joi.string().required(),
|
||||
}).required());
|
||||
|
||||
registerEndpoint("/rotate-pdf", "", upload.single("file"), Operations.rotatePages, Joi.object({
|
||||
file: PdfFileSchema.required(),
|
||||
rotation: Joi.alternatives().try(Joi.number(), Joi.array().items(Joi.number())).required(),
|
||||
}).required())
|
||||
}).required());
|
||||
|
||||
registerEndpoint("/update-metadata", "_edited-metadata", upload.single("file"), Operations.updateMetadata, Joi.object({
|
||||
registerEndpoint("/update-metadata", "", upload.single("file"), Operations.updateMetadata, Joi.object({
|
||||
file: PdfFileSchema.required(),
|
||||
deleteAll: Joi.string(),
|
||||
author: Joi.string(),
|
||||
@@ -75,6 +77,6 @@ registerEndpoint("/update-metadata", "_edited-metadata", upload.single("file"),
|
||||
title: Joi.string(),
|
||||
trapped: Joi.string(),
|
||||
allRequestParams: Joi.object().pattern(Joi.string(), Joi.string()),
|
||||
}).required())
|
||||
}).required());
|
||||
|
||||
export default router;
|
||||
@@ -1,13 +1,12 @@
|
||||
import express, { Request, Response } from 'express';
|
||||
import crypto from 'crypto';
|
||||
import stream from "stream";
|
||||
import Archiver from 'archiver';
|
||||
import multer from 'multer'
|
||||
const upload = multer();
|
||||
|
||||
import Operations from "../../utils/pdf-operations";
|
||||
import { traverseOperations } from "@stirling-pdf/shared-operations/src/workflow/traverseOperations";
|
||||
import { PdfFile, RepresentationType } from '@stirling-pdf/shared-operations/src/wrappers/PdfFile';
|
||||
import { respondWithPdfFiles } from '../../utils/endpoint-utils';
|
||||
|
||||
const activeWorkflows: any = {};
|
||||
|
||||
@@ -50,7 +49,7 @@ router.post("/:workflowUuid?", [
|
||||
}
|
||||
|
||||
console.log("Download");
|
||||
await downloadHandler(res, pdfResults);
|
||||
await respondWithPdfFiles(res, pdfResults, "workflow-results");
|
||||
}
|
||||
else {
|
||||
console.log("Start Aync Workflow");
|
||||
@@ -164,7 +163,7 @@ router.get("/result/:workflowUuid", async (req: Request, res: Response) => {
|
||||
return
|
||||
}
|
||||
|
||||
await downloadHandler(res, workflow.result);
|
||||
await respondWithPdfFiles(res, workflow.result, "workflow-results");
|
||||
// Delete workflow / results when done.
|
||||
delete activeWorkflows[req.params.workflowUuid];
|
||||
});
|
||||
@@ -187,43 +186,4 @@ function generateWorkflowID() {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
|
||||
async function downloadHandler(res: Response, pdfResults: PdfFile[]) {
|
||||
if(pdfResults.length == 0) {
|
||||
res.status(500).json({"warning": "The workflow had no outputs."});
|
||||
}
|
||||
else if(pdfResults.length > 1) {
|
||||
// TODO: Also allow the user to download multiple files without zip compressen, because this is kind of slow...
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/zip',
|
||||
'Content-disposition': 'attachment; filename=workflow-results.zip'
|
||||
});
|
||||
|
||||
var zip = Archiver('zip');
|
||||
|
||||
// Stream the file to the user.
|
||||
zip.pipe(res);
|
||||
|
||||
console.log("Adding Files to ZIP...");
|
||||
|
||||
for (let i = 0; i < pdfResults.length; i++) {
|
||||
// TODO: Implement other file types (mostly fro image & text extraction)
|
||||
// TODO: Check for name collisions
|
||||
zip.append(Buffer.from(await pdfResults[i].uint8Array), { name: pdfResults[i].filename + ".pdf" });
|
||||
}
|
||||
|
||||
zip.finalize();
|
||||
console.log("Sent");
|
||||
}
|
||||
else {
|
||||
const readStream = new stream.PassThrough();
|
||||
readStream.end(await pdfResults[0].uint8Array);
|
||||
|
||||
// TODO: Implement other file types (mostly fro image & text extraction)
|
||||
res.set("Content-disposition", 'attachment; filename=' + pdfResults[0].filename + ".pdf");
|
||||
res.set("Content-Type", "application/pdf");
|
||||
|
||||
readStream.pipe(res);
|
||||
}
|
||||
}
|
||||
|
||||
export default router;
|
||||
@@ -1,19 +1,64 @@
|
||||
|
||||
import { Response } from 'express';
|
||||
import { PdfFile } from '@stirling-pdf/shared-operations/src/wrappers/PdfFile'
|
||||
import Archiver from 'archiver';
|
||||
|
||||
export async function respondWithFile(res: Response, bytes: Uint8Array, name: string, mimeType: string): Promise<void> {
|
||||
export async function respondWithFile(res: Response, uint8Array: Uint8Array, filename: string, mimeType: string): Promise<void> {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': mimeType,
|
||||
'Content-disposition': 'attachment;filename=' + name,
|
||||
'Content-Length': bytes.length
|
||||
'Content-disposition': `attachment; filename="${filename}"`,
|
||||
'Content-Length': uint8Array.length
|
||||
});
|
||||
res.end(bytes);
|
||||
res.end(uint8Array);
|
||||
}
|
||||
|
||||
export async function respondWithPdfFile(res: Response, file: PdfFile): Promise<void> {
|
||||
const byteArray = await file.uint8Array;
|
||||
respondWithFile(res, byteArray, file.filename, "application/pdf");
|
||||
respondWithFile(res, byteArray, file.filename+".pdf", "application/pdf");
|
||||
}
|
||||
|
||||
export async function respondWithZip(res: Response, filename: string, files: {uint8Array: Uint8Array, filename: string}[]): Promise<void> {
|
||||
if (files.length == 0) {
|
||||
res.status(500).json({"warning": "The workflow had no outputs."});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(filename)
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/zip',
|
||||
'Content-disposition': `attachment; filename="${filename}.zip"`,
|
||||
});
|
||||
|
||||
// TODO: Also allow changing the compression level
|
||||
var zip = Archiver('zip');
|
||||
|
||||
// Stream the file to the user.
|
||||
zip.pipe(res);
|
||||
|
||||
console.log("Adding Files to ZIP...");
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
zip.append(Buffer.from(files[i].uint8Array), { name: files[i].filename });
|
||||
}
|
||||
|
||||
zip.finalize();
|
||||
console.log("Sent");
|
||||
}
|
||||
|
||||
export async function respondWithPdfFiles(res: Response, pdfFiles: PdfFile|PdfFile[], filename: string) {
|
||||
const pdfResults = Array.isArray(pdfFiles) ? pdfFiles : [pdfFiles];
|
||||
|
||||
if(pdfResults.length == 0) {
|
||||
res.status(500).json({"warning": "The workflow had no outputs."});
|
||||
}
|
||||
else if (pdfResults.length == 1) {
|
||||
respondWithPdfFile(res, pdfResults[0])
|
||||
}
|
||||
else {
|
||||
const promises = pdfResults.map(async (pdf) => {return{uint8Array: await pdf.uint8Array, filename: pdf.filename + ".pdf"}})
|
||||
const files = await Promise.all(promises);
|
||||
respondWithZip(res, filename, files);
|
||||
}
|
||||
}
|
||||
|
||||
export function response_mustHaveExactlyOneFile(res: Response): void {
|
||||
|
||||
Reference in New Issue
Block a user