mirror of
				https://github.com/Frooodle/Stirling-PDF.git
				synced 2025-10-25 11:17:28 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			250 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { extractPages } from "./functions/extractPages.js";
 | |
| import { impose } from "./functions/impose.js";
 | |
| import { mergePDFs } from "./functions/mergePDFs.js";
 | |
| import { rotatePages } from "./functions/rotatePDF.js";
 | |
| import { splitPDF } from "./functions/splitPDF.js";
 | |
| import { organizeWaitOperations } from "./public/organizeWaitOperations.js";
 | |
| 
 | |
| export async function * traverseOperations(operations, input) {
 | |
|     const waitOperations = organizeWaitOperations(operations);
 | |
|     let results = [];
 | |
|     for await (const value of nextOperation(operations, input)) {
 | |
|         yield value;
 | |
|     }
 | |
|     return results;
 | |
| 
 | |
|     // TODO: Pult all nextOperation() in the for await, like for "extract"
 | |
|     async function * nextOperation(operations, input) {
 | |
|         if(Array.isArray(operations) && operations.length == 0) { // isEmpty
 | |
|             if(Array.isArray(input)) {
 | |
|                 console.log("operation done: " + input[0].fileName + "+");
 | |
|                 results = results.concat(input);
 | |
|                 return;
 | |
|             }
 | |
|             else {
 | |
|                 console.log("operation done: " + input.fileName);
 | |
|                 results.push(input);
 | |
|                 return;
 | |
|             }
 | |
|         }
 | |
|     
 | |
|         for (let i = 0; i < operations.length; i++) {
 | |
|             for await (const value of computeOperation(operations[i], structuredClone(input))) {
 | |
|                 yield value;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     async function * computeOperation(operation, input) {
 | |
|         switch (operation.type) {
 | |
|             case "done":
 | |
|                 console.log("Done operation will get called if all waits are done. Skipping for now.")
 | |
|                 break;
 | |
|             case "wait":
 | |
|                 const waitOperation = waitOperations[operation.values.id];
 | |
| 
 | |
|                 if(Array.isArray(input)) {
 | |
|                     // waitOperation.input.concat(input); // May have unexpected concequences. Better throw an error for now.
 | |
|                     throw new Error("Wait recieved an array as input. I don't know if this can happen, but if it does happen, I will investigate. Please share your workflow (:");
 | |
|                 }
 | |
|                 else {
 | |
|                     waitOperation.input.push(input);
 | |
|                 }
 | |
| 
 | |
|                 // Wait for all elements of previous split to finish
 | |
|                 if(input.splitCount && input.splitCount > 0) {
 | |
|                     input.splitCount--;
 | |
|                     return;
 | |
|                 }
 | |
| 
 | |
|                 waitOperation.waitCount--;
 | |
|                 if(waitOperation.waitCount == 0) {
 | |
|                     await nextOperation(waitOperation.doneOperation.operations, waitOperation.input);
 | |
|                 }
 | |
|                 break;
 | |
|             case "removeObjects":
 | |
|                 console.warn("RemoveObjects not implemented yet.")
 | |
| 
 | |
|                 if(Array.isArray(input)) {
 | |
|                     for (let i = 0; i < input.length; i++) {
 | |
|                         // TODO: modfiy input
 | |
|                         input[i].fileName += "_removedObjects";
 | |
|                         await nextOperation(operation.operations, input[i]);
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     // TODO: modfiy input
 | |
|                     input.fileName += "_removedObjects";
 | |
|                     await nextOperation(operation.operations, input);
 | |
|                 }
 | |
|                 break;
 | |
|             case "extract":
 | |
|                 if(Array.isArray(input)) {
 | |
|                     for (let i = 0; i < input.length; i++) {
 | |
|                         input[i].fileName += "_extractedPages";
 | |
|                         input[i].buffer = await extractPages(input[i].buffer, operation.values["pagesToExtractArray"]);
 | |
|                         for await (const value of nextOperation(operation.operations, input[i])) {
 | |
|                             yield value;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     input.fileName += "_extractedPages";
 | |
|                     input.buffer = await extractPages(input.buffer, operation.values["pagesToExtractArray"]);
 | |
|                     for await (const value of nextOperation(operation.operations, input)) {
 | |
|                         yield value;
 | |
|                     }
 | |
|                 }
 | |
|                 break;
 | |
|             case "split":
 | |
|                 // TODO: When a split goes into another split function and then into a wait function it might break the done condition, as it will count multiple times.
 | |
|                 if(Array.isArray(input)) {
 | |
|                     for (let i = 0; i < input.length; i++) {
 | |
|                         const splitResult = await splitPDF(input[i].buffer, operation.values["pagesToSplitAfterArray"]);
 | |
| 
 | |
|                         const splits = [];
 | |
|                         for (let j = 0; j < splitResult.length; j++) {
 | |
|                             splits.push({
 | |
|                                 originalFileName: input[i].originalFileName,
 | |
|                                 fileName: input[i].fileName + "_split" + j,
 | |
|                                 buffer: splitResult[j],
 | |
|                                 splitCount: splitResult.length
 | |
|                             })
 | |
|                         }
 | |
|                         console.log(splits);
 | |
| 
 | |
|                         for await (const value of nextOperation(operation.operations, splits)) {
 | |
|                             yield value;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     const splitResult = await splitPDF(input.buffer, operation.values["pagesToSplitAfterArray"]);
 | |
| 
 | |
|                     const splits = [];
 | |
|                     for (let j = 0; j < splitResult.length; j++) {
 | |
|                         splits.push({
 | |
|                             originalFileName: input.originalFileName,
 | |
|                             fileName: input.fileName + "_split" + j,
 | |
|                             buffer: splitResult[j],
 | |
|                             splitCount: splitResult.length
 | |
|                         })
 | |
|                     }
 | |
|                     
 | |
|                     for await (const value of nextOperation(operation.operations, splits)) {
 | |
|                         yield value;
 | |
|                     }
 | |
|                 }
 | |
|                 break;
 | |
|             case "fillField":
 | |
|                 console.warn("FillField not implemented yet.")
 | |
| 
 | |
|                 if(Array.isArray(input)) {
 | |
|                     for (let i = 0; i < input.length; i++) {
 | |
|                         // TODO: modfiy input
 | |
|                         input[i].fileName += "_filledField";
 | |
|                         await nextOperation(operation.operations, input[i]);
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     // TODO: modfiy input
 | |
|                     input.fileName += "_filledField";
 | |
|                     await nextOperation(operation.operations, input);
 | |
|                 }
 | |
|                 break;
 | |
|             case "extractImages":
 | |
|                 console.warn("ExtractImages not implemented yet.")
 | |
| 
 | |
|                 if(Array.isArray(input)) {
 | |
|                     for (let i = 0; i < input.length; i++) {
 | |
|                         // TODO: modfiy input
 | |
|                         input[i].fileName += "_extractedImages";
 | |
|                         await nextOperation(operation.operations, input[i]);
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     // TODO: modfiy input
 | |
|                     input.fileName += "_extractedImages";
 | |
|                     await nextOperation(operation.operations, input);
 | |
|                 }
 | |
|                 break;
 | |
|             case "merge":
 | |
|                 if(Array.isArray(input) && input.length > 1) {
 | |
|                     const inputs = input;
 | |
|                     input = {
 | |
|                         originalFileName: inputs.map(input => input.originalFileName).join("_and_"),
 | |
|                         fileName: inputs.map(input => input.fileName).join("_and_") + "_merged",
 | |
|                         buffer: await mergePDFs(inputs.map(input => input.buffer))
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     // Only one input, no need to merge
 | |
|                     input.fileName += "_merged";
 | |
|                 }
 | |
|                 await nextOperation(operation.operations, input);
 | |
|                 break;
 | |
|             case "transform": {
 | |
|                 console.warn("Transform not implemented yet.")
 | |
|                 if(Array.isArray(input)) {
 | |
|                     for (let i = 0; i < input.length; i++) {
 | |
|                         // TODO: modfiy input
 | |
|                         input[i].fileName += "_transformed";
 | |
|                         await nextOperation(operation.operations, input[i]);
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     // TODO: modfiy input
 | |
|                     input.fileName += "_transformed";
 | |
|                     await nextOperation(operation.operations, input);
 | |
|                 }
 | |
|                 break;
 | |
|             }
 | |
|             case "extract":
 | |
|                 if(Array.isArray(input)) {
 | |
|                     for (let i = 0; i < input.length; i++) {
 | |
|                         input[i].fileName += "_extractedPages";
 | |
|                         input[i].buffer = await extractPages(input[i].buffer, operation.values["pagesToExtractArray"]);
 | |
|                         await nextOperation(operation.operations, input[i]);
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     input.fileName += "_extractedPages";
 | |
|                     input.buffer = await extractPages(input.buffer, operation.values["pagesToExtractArray"]);
 | |
|                     await nextOperation(operation.operations, input);
 | |
|                 }
 | |
|                 break;
 | |
|             case "rotate":
 | |
|                 if(Array.isArray(input)) {
 | |
|                     for (let i = 0; i < input.length; i++) {
 | |
|                         input[i].fileName += "_turned";
 | |
|                         input[i].buffer = await rotatePages(input[i].buffer, operation.values["rotation"]);
 | |
|                         await nextOperation(operation.operations, input[i]);
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     input.fileName += "_turned";
 | |
|                     input.buffer = await rotatePages(input.buffer, operation.values["rotation"]);
 | |
|                     await nextOperation(operation.operations, input);
 | |
|                 }
 | |
|                 break;
 | |
|             case "impose":
 | |
|                 if(Array.isArray(input)) {
 | |
|                     for (let i = 0; i < input.length; i++) {
 | |
|                         input[i].fileName += "_imposed";
 | |
|                         input[i].buffer = await impose(input[i].buffer, operation.values["nup"], operation.values["format"]);
 | |
|                         await nextOperation(operation.operations, input[i]);
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     input.fileName += "_imposed";
 | |
|                     input.buffer = await impose(input.buffer, operation.values["nup"], operation.values["format"]);
 | |
|                     await nextOperation(operation.operations, input);
 | |
|                 }
 | |
|                 break;
 | |
|             default:
 | |
|                 console.log("operation type unknown: ", operation.type);
 | |
|                 break;
 | |
|         }
 | |
|         yield operation.type;
 | |
|     }
 | |
| } |