From 9af1b0cfdc2e2393e67a19e495a83d723ca4270f Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Sat, 15 Jul 2023 16:06:33 +0100 Subject: [PATCH] some more changes also broke pipeline a bit --- .../api/filters/FilterController.java | 333 +++++++++--------- .../api/other/AutoSplitPdfController.java | 7 +- ...ontroller.java => PipelineController.java} | 45 ++- .../api/security/WatermarkController.java | 45 ++- .../software/SPDF/utils/PdfUtils.java | 2 +- src/main/resources/static/js/pipeline.js | 113 +++--- src/main/resources/templates/pipeline.html | 198 ++++++----- 7 files changed, 430 insertions(+), 313 deletions(-) rename src/main/java/stirling/software/SPDF/controller/api/pipeline/{Controller.java => PipelineController.java} (89%) diff --git a/src/main/java/stirling/software/SPDF/controller/api/filters/FilterController.java b/src/main/java/stirling/software/SPDF/controller/api/filters/FilterController.java index 13732ba3..72eefe84 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/filters/FilterController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/filters/FilterController.java @@ -1,162 +1,171 @@ -package stirling.software.SPDF.controller.api.filters; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.common.PDRectangle; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import stirling.software.SPDF.utils.PdfUtils; -import stirling.software.SPDF.utils.ProcessExecutor; -import stirling.software.SPDF.utils.WebResponseUtils; - -@RestController -@Tag(name = "Filter", description = "Filter APIs") -public class FilterController { - - @PostMapping(consumes = "multipart/form-data", value = "/contains-text") - @Operation(summary = "Checks if a PDF contains set text, returns true if does", description = "Input:PDF Output:Boolean Type:SISO") - public Boolean containsText( - @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to be converted to a PDF/A file", required = true) MultipartFile inputFile, - @Parameter(description = "The text to check for", required = true) String text, - @Parameter(description = "The page number to check for text on accepts 'All', ranges like '1-4'", required = false) String pageNumber) - throws IOException, InterruptedException { - PDDocument pdfDocument = PDDocument.load(inputFile.getInputStream()); - return PdfUtils.hasText(pdfDocument, pageNumber); - } - - @PostMapping(consumes = "multipart/form-data", value = "/contains-image") - @Operation(summary = "Checks if a PDF contains an image", description = "Input:PDF Output:Boolean Type:SISO") - public Boolean containsImage( - @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to be converted to a PDF/A file", required = true) MultipartFile inputFile, - @Parameter(description = "The page number to check for image on accepts 'All', ranges like '1-4'", required = false) String pageNumber) - throws IOException, InterruptedException { - PDDocument pdfDocument = PDDocument.load(inputFile.getInputStream()); - return PdfUtils.hasImagesOnPage(null); - } - - @PostMapping(consumes = "multipart/form-data", value = "/page-count") - @Operation(summary = "Checks if a PDF is greater, less or equal to a setPageCount", description = "Input:PDF Output:Boolean Type:SISO") - public Boolean pageCount( - @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile, - @Parameter(description = "Page Count", required = true) String pageCount, - @Parameter(description = "Comparison type, accepts Greater, Equal, Less than", required = false) String comparator) - throws IOException, InterruptedException { - // Load the PDF - PDDocument document = PDDocument.load(inputFile.getInputStream()); - int actualPageCount = document.getNumberOfPages(); - - // Perform the comparison - switch (comparator) { - case "Greater": - return actualPageCount > Integer.parseInt(pageCount); - case "Equal": - return actualPageCount == Integer.parseInt(pageCount); - case "Less": - return actualPageCount < Integer.parseInt(pageCount); - default: - throw new IllegalArgumentException("Invalid comparator: " + comparator); - } - } - - @PostMapping(consumes = "multipart/form-data", value = "/page-size") - @Operation(summary = "Checks if a PDF is of a certain size", description = "Input:PDF Output:Boolean Type:SISO") - public Boolean pageSize( - @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile, - @Parameter(description = "Standard Page Size", required = true) String standardPageSize, - @Parameter(description = "Comparison type, accepts Greater, Equal, Less than", required = false) String comparator) - throws IOException, InterruptedException { - - // Load the PDF - PDDocument document = PDDocument.load(inputFile.getInputStream()); - - PDPage firstPage = document.getPage(0); - PDRectangle actualPageSize = firstPage.getMediaBox(); - - // Calculate the area of the actual page size - float actualArea = actualPageSize.getWidth() * actualPageSize.getHeight(); - - // Get the standard size and calculate its area - PDRectangle standardSize = PdfUtils.textToPageSize(standardPageSize); - float standardArea = standardSize.getWidth() * standardSize.getHeight(); - - // Perform the comparison - switch (comparator) { - case "Greater": - return actualArea > standardArea; - case "Equal": - return actualArea == standardArea; - case "Less": - return actualArea < standardArea; - default: - throw new IllegalArgumentException("Invalid comparator: " + comparator); - } - } - - - @PostMapping(consumes = "multipart/form-data", value = "/file-size") - @Operation(summary = "Checks if a PDF is a set file size", description = "Input:PDF Output:Boolean Type:SISO") - public Boolean fileSize( - @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile, - @Parameter(description = "File Size", required = true) String fileSize, - @Parameter(description = "Comparison type, accepts Greater, Equal, Less than", required = false) String comparator) - throws IOException, InterruptedException { - - // Get the file size - long actualFileSize = inputFile.getSize(); - - // Perform the comparison - switch (comparator) { - case "Greater": - return actualFileSize > Long.parseLong(fileSize); - case "Equal": - return actualFileSize == Long.parseLong(fileSize); - case "Less": - return actualFileSize < Long.parseLong(fileSize); - default: - throw new IllegalArgumentException("Invalid comparator: " + comparator); - } - } - - - @PostMapping(consumes = "multipart/form-data", value = "/page-rotation") - @Operation(summary = "Checks if a PDF is of a certain rotation", description = "Input:PDF Output:Boolean Type:SISO") - public Boolean pageRotation( - @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile, - @Parameter(description = "Rotation in degrees", required = true) int rotation, - @Parameter(description = "Comparison type, accepts Greater, Equal, Less than", required = false) String comparator) - throws IOException, InterruptedException { - - // Load the PDF - PDDocument document = PDDocument.load(inputFile.getInputStream()); - - // Get the rotation of the first page - PDPage firstPage = document.getPage(0); - int actualRotation = firstPage.getRotation(); - - // Perform the comparison - switch (comparator) { - case "Greater": - return actualRotation > rotation; - case "Equal": - return actualRotation == rotation; - case "Less": - return actualRotation < rotation; - default: - throw new IllegalArgumentException("Invalid comparator: " + comparator); - } - } - -} +package stirling.software.SPDF.controller.api.filters; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import stirling.software.SPDF.utils.PdfUtils; +import stirling.software.SPDF.utils.ProcessExecutor; +import stirling.software.SPDF.utils.WebResponseUtils; +import io.swagger.v3.oas.annotations.media.Schema; +@RestController +@Tag(name = "Filter", description = "Filter APIs") +public class FilterController { + + @PostMapping(consumes = "multipart/form-data", value = "/contains-text") + @Operation(summary = "Checks if a PDF contains set text, returns true if does", description = "Input:PDF Output:Boolean Type:SISO") + public Boolean containsText( + @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to be converted to a PDF/A file", required = true) MultipartFile inputFile, + @Parameter(description = "The text to check for", required = true) String text, + @Parameter(description = "The page number to check for text on accepts 'All', ranges like '1-4'", required = false) String pageNumber) + throws IOException, InterruptedException { + PDDocument pdfDocument = PDDocument.load(inputFile.getInputStream()); + return PdfUtils.hasText(pdfDocument, pageNumber); + } + + //TODO + @PostMapping(consumes = "multipart/form-data", value = "/contains-image") + @Operation(summary = "Checks if a PDF contains an image", description = "Input:PDF Output:Boolean Type:SISO") + public Boolean containsImage( + @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to be converted to a PDF/A file", required = true) MultipartFile inputFile, + @Parameter(description = "The page number to check for image on accepts 'All', ranges like '1-4'", required = false) String pageNumber) + throws IOException, InterruptedException { + PDDocument pdfDocument = PDDocument.load(inputFile.getInputStream()); + return PdfUtils.hasImagesOnPage(null); + } + + @PostMapping(consumes = "multipart/form-data", value = "/page-count") + @Operation(summary = "Checks if a PDF is greater, less or equal to a setPageCount", description = "Input:PDF Output:Boolean Type:SISO") + public Boolean pageCount( + @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile, + @Parameter(description = "Page Count", required = true) String pageCount, + @Parameter(description = "Comparison type", + schema = @Schema(description = "The comparison type, accepts Greater, Equal, Less than", + allowableValues = {"Greater", "Equal", "Less"})) String comparator) + throws IOException, InterruptedException { + // Load the PDF + PDDocument document = PDDocument.load(inputFile.getInputStream()); + int actualPageCount = document.getNumberOfPages(); + + // Perform the comparison + switch (comparator) { + case "Greater": + return actualPageCount > Integer.parseInt(pageCount); + case "Equal": + return actualPageCount == Integer.parseInt(pageCount); + case "Less": + return actualPageCount < Integer.parseInt(pageCount); + default: + throw new IllegalArgumentException("Invalid comparator: " + comparator); + } + } + + @PostMapping(consumes = "multipart/form-data", value = "/page-size") + @Operation(summary = "Checks if a PDF is of a certain size", description = "Input:PDF Output:Boolean Type:SISO") + public Boolean pageSize( + @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile, + @Parameter(description = "Standard Page Size", required = true) String standardPageSize, + @Parameter(description = "Comparison type", + schema = @Schema(description = "The comparison type, accepts Greater, Equal, Less than", + allowableValues = {"Greater", "Equal", "Less"})) String comparator) + throws IOException, InterruptedException { + + // Load the PDF + PDDocument document = PDDocument.load(inputFile.getInputStream()); + + PDPage firstPage = document.getPage(0); + PDRectangle actualPageSize = firstPage.getMediaBox(); + + // Calculate the area of the actual page size + float actualArea = actualPageSize.getWidth() * actualPageSize.getHeight(); + + // Get the standard size and calculate its area + PDRectangle standardSize = PdfUtils.textToPageSize(standardPageSize); + float standardArea = standardSize.getWidth() * standardSize.getHeight(); + + // Perform the comparison + switch (comparator) { + case "Greater": + return actualArea > standardArea; + case "Equal": + return actualArea == standardArea; + case "Less": + return actualArea < standardArea; + default: + throw new IllegalArgumentException("Invalid comparator: " + comparator); + } + } + + + @PostMapping(consumes = "multipart/form-data", value = "/file-size") + @Operation(summary = "Checks if a PDF is a set file size", description = "Input:PDF Output:Boolean Type:SISO") + public Boolean fileSize( + @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile, + @Parameter(description = "File Size", required = true) String fileSize, + @Parameter(description = "Comparison type", + schema = @Schema(description = "The comparison type, accepts Greater, Equal, Less than", + allowableValues = {"Greater", "Equal", "Less"})) String comparator) + throws IOException, InterruptedException { + + // Get the file size + long actualFileSize = inputFile.getSize(); + + // Perform the comparison + switch (comparator) { + case "Greater": + return actualFileSize > Long.parseLong(fileSize); + case "Equal": + return actualFileSize == Long.parseLong(fileSize); + case "Less": + return actualFileSize < Long.parseLong(fileSize); + default: + throw new IllegalArgumentException("Invalid comparator: " + comparator); + } + } + + + @PostMapping(consumes = "multipart/form-data", value = "/page-rotation") + @Operation(summary = "Checks if a PDF is of a certain rotation", description = "Input:PDF Output:Boolean Type:SISO") + public Boolean pageRotation( + @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file", required = true) MultipartFile inputFile, + @Parameter(description = "Rotation in degrees", required = true) int rotation, + @Parameter(description = "Comparison type", + schema = @Schema(description = "The comparison type, accepts Greater, Equal, Less than", + allowableValues = {"Greater", "Equal", "Less"})) String comparator) + throws IOException, InterruptedException { + + // Load the PDF + PDDocument document = PDDocument.load(inputFile.getInputStream()); + + // Get the rotation of the first page + PDPage firstPage = document.getPage(0); + int actualRotation = firstPage.getRotation(); + + // Perform the comparison + switch (comparator) { + case "Greater": + return actualRotation > rotation; + case "Equal": + return actualRotation == rotation; + case "Less": + return actualRotation < rotation; + default: + throw new IllegalArgumentException("Invalid comparator: " + comparator); + } + } + +} diff --git a/src/main/java/stirling/software/SPDF/controller/api/other/AutoSplitPdfController.java b/src/main/java/stirling/software/SPDF/controller/api/other/AutoSplitPdfController.java index c706cba7..e69c0597 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/other/AutoSplitPdfController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/other/AutoSplitPdfController.java @@ -30,6 +30,8 @@ import com.google.zxing.Result; import com.google.zxing.common.HybridBinarizer; import stirling.software.SPDF.utils.WebResponseUtils; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; @RestController public class AutoSplitPdfController { @@ -37,7 +39,10 @@ public class AutoSplitPdfController { private static final String QR_CONTENT = "https://github.com/Frooodle/Stirling-PDF"; @PostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data") - public ResponseEntity autoSplitPdf(@RequestParam("fileInput") MultipartFile file) throws IOException { + @Operation(summary = "Auto split PDF pages into separate documents", description = "This endpoint accepts a PDF file, scans each page for a specific QR code, and splits the document at the QR code boundaries. The output is a zip file containing each separate PDF document. Input:PDF Output:ZIP Type:SISO") + public ResponseEntity autoSplitPdf( + @RequestParam("fileInput") @Parameter(description = "The input PDF file which needs to be split into separate documents based on QR code boundaries.", required = true) MultipartFile file) + throws IOException { InputStream inputStream = file.getInputStream(); PDDocument document = PDDocument.load(inputStream); PDFRenderer pdfRenderer = new PDFRenderer(document); diff --git a/src/main/java/stirling/software/SPDF/controller/api/pipeline/Controller.java b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java similarity index 89% rename from src/main/java/stirling/software/SPDF/controller/api/pipeline/Controller.java rename to src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java index 8193e0c8..feeefbd0 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/pipeline/Controller.java +++ b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java @@ -53,9 +53,9 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @Tag(name = "Pipeline", description = "Pipeline APIs") -public class Controller { +public class PipelineController { - private static final Logger logger = LoggerFactory.getLogger(Controller.class); + private static final Logger logger = LoggerFactory.getLogger(PipelineController.class); @Autowired private ObjectMapper objectMapper; @@ -246,11 +246,11 @@ public class Controller { List processFiles(List outputFiles, String jsonString) throws Exception { - logger.info("Processing files... " + outputFiles); ObjectMapper mapper = new ObjectMapper(); JsonNode jsonNode = mapper.readTree(jsonString); JsonNode pipelineNode = jsonNode.get("pipeline"); + logger.info("Running pipelineNode: {}", pipelineNode); ByteArrayOutputStream logStream = new ByteArrayOutputStream(); PrintStream logPrintStream = new PrintStream(logStream); @@ -298,19 +298,32 @@ public class Controller { continue; } - // Check if the response body is a zip file - if (isZip(response.getBody())) { - // Unzip the file and add all the files to the new output files - newOutputFiles.addAll(unzip(response.getBody())); - } else { - Resource outputResource = new ByteArrayResource(response.getBody()) { - @Override - public String getFilename() { - return file.getFilename(); // Preserving original filename - } - }; - newOutputFiles.add(outputResource); - } + + // Define filename + String filename; + if ("auto-rename".equals(operation)) { + // If the operation is "auto-rename", generate a new filename. + // This is a simple example of generating a filename using current timestamp. + // Modify as per your needs. + filename = "file_" + System.currentTimeMillis(); + } else { + // Otherwise, keep the original filename. + filename = file.getFilename(); + } + + // Check if the response body is a zip file + if (isZip(response.getBody())) { + // Unzip the file and add all the files to the new output files + newOutputFiles.addAll(unzip(response.getBody())); + } else { + Resource outputResource = new ByteArrayResource(response.getBody()) { + @Override + public String getFilename() { + return filename; + } + }; + newOutputFiles.add(outputResource); + } } if (!hasInputFileType) { diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java b/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java index 962f578e..a8271207 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/WatermarkController.java @@ -47,6 +47,11 @@ public class WatermarkController { @RequestPart(required = true) @Parameter(description = "The watermark type (text or image)") String watermarkType, @RequestPart(required = false) @Parameter(description = "The watermark text") String watermarkText, @RequestPart(required = false) @Parameter(description = "The watermark image") MultipartFile watermarkImage, + + @RequestParam(defaultValue = "roman", name = "alphabet") @Parameter(description = "The selected alphabet", + schema = @Schema(type = "string", + allowableValues = {"roman","arabic","japanese","korean","chinese"}, + defaultValue = "roman")) String alphabet, @RequestParam(defaultValue = "30", name = "fontSize") @Parameter(description = "The font size of the watermark text", example = "30") float fontSize, @RequestParam(defaultValue = "0", name = "rotation") @Parameter(description = "The rotation of the watermark in degrees", example = "0") float rotation, @RequestParam(defaultValue = "0.5", name = "opacity") @Parameter(description = "The opacity of the watermark (0.0 - 1.0)", example = "0.5") float opacity, @@ -71,7 +76,7 @@ public class WatermarkController { if (watermarkType.equalsIgnoreCase("text")) { addTextWatermark(contentStream, watermarkText, document, page, rotation, widthSpacer, heightSpacer, - fontSize); + fontSize, alphabet); } else if (watermarkType.equalsIgnoreCase("image")) { addImageWatermark(contentStream, watermarkImage, document, page, rotation, widthSpacer, heightSpacer, fontSize); @@ -86,9 +91,41 @@ public class WatermarkController { } private void addTextWatermark(PDPageContentStream contentStream, String watermarkText, PDDocument document, - PDPage page, float rotation, int widthSpacer, int heightSpacer, float fontSize) throws IOException { - // Set font and other properties for text watermark - PDFont font = PDType1Font.HELVETICA_BOLD; + PDPage page, float rotation, int widthSpacer, int heightSpacer, float fontSize, String alphabet) throws IOException { + String resourceDir = ""; + PDFont font = PDType1Font.HELVETICA_BOLD; + switch (alphabet) { + case "arabic": + resourceDir = "static/fonts/NotoSansArabic-Regular.ttf"; + break; + case "japanese": + resourceDir = "static/fonts/Meiryo.ttf"; + break; + case "korean": + resourceDir = "static/fonts/malgun.ttf"; + break; + case "chinese": + resourceDir = "static/fonts/SimSun.ttf"; + break; + case "roman": + default: + resourceDir = "static/fonts/NotoSans-Regular.ttf"; + break; + } + + + if(!resourceDir.equals("")) { + ClassPathResource classPathResource = new ClassPathResource(resourceDir); + String fileExtension = resourceDir.substring(resourceDir.lastIndexOf(".")); + File tempFile = File.createTempFile("NotoSansFont", fileExtension); + try (InputStream is = classPathResource.getInputStream(); FileOutputStream os = new FileOutputStream(tempFile)) { + IOUtils.copy(is, os); + } + + font = PDType0Font.load(document, tempFile); + tempFile.deleteOnExit(); + } + contentStream.setFont(font, fontSize); contentStream.setNonStrokingColor(Color.LIGHT_GRAY); diff --git a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java index 5e9d53b0..43e26017 100644 --- a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java @@ -44,7 +44,7 @@ public class PdfUtils { public static PDRectangle textToPageSize(String size) { - switch (size) { + switch (size.toUpperCase()) { case "A0": return PDRectangle.A0; case "A1": diff --git a/src/main/resources/static/js/pipeline.js b/src/main/resources/static/js/pipeline.js index 85918cd5..c2c4601a 100644 --- a/src/main/resources/static/js/pipeline.js +++ b/src/main/resources/static/js/pipeline.js @@ -87,7 +87,7 @@ document.getElementById('submitConfigBtn').addEventListener('click', function() let formData = new FormData(); - let fileInput = document.getElementById('fileInput'); + let fileInput = document.getElementById('fileInput-input'); let files = fileInput.files; for (let i = 0; i < files.length; i++) { @@ -177,7 +177,11 @@ document.getElementById('addOperationBtn').addEventListener('click', function() let listItem = document.createElement('li'); listItem.className = "list-group-item"; let hasSettings = (apiDocs[selectedOperation] && apiDocs[selectedOperation].post && - apiDocs[selectedOperation].post.parameters && apiDocs[selectedOperation].post.parameters.length > 0); + ((apiDocs[selectedOperation].post.parameters && apiDocs[selectedOperation].post.parameters.length > 0) || + (apiDocs[selectedOperation].post.requestBody && + apiDocs[selectedOperation].post.requestBody.content['multipart/form-data'].schema.properties))); + + listItem.innerHTML = ` @@ -222,52 +226,77 @@ document.getElementById('addOperationBtn').addEventListener('click', function() let pipelineSettingsModal = document.getElementById('pipelineSettingsModal'); let pipelineSettingsContent = document.getElementById('pipelineSettingsContent'); let operationData = apiDocs[operation].post.parameters || []; + let requestBodyData = apiDocs[operation].post.requestBody.content['multipart/form-data'].schema.properties || {}; + + // Combine operationData and requestBodyData into a single array + operationData = operationData.concat(Object.keys(requestBodyData).map(key => ({ + name: key, + schema: requestBodyData[key] + }))); pipelineSettingsContent.innerHTML = ''; operationData.forEach(parameter => { - let parameterDiv = document.createElement('div'); - parameterDiv.className = "form-group"; + let parameterDiv = document.createElement('div'); + parameterDiv.className = "form-group"; - let parameterLabel = document.createElement('label'); - parameterLabel.textContent = `${parameter.name} (${parameter.schema.type}): `; - parameterLabel.title = parameter.description; - parameterDiv.appendChild(parameterLabel); + let parameterLabel = document.createElement('label'); + parameterLabel.textContent = `${parameter.name} (${parameter.schema.type}): `; + parameterLabel.title = parameter.description; + parameterDiv.appendChild(parameterLabel); - let parameterInput; - switch (parameter.schema.type) { - case 'string': - case 'number': - case 'integer': - parameterInput = document.createElement('input'); - parameterInput.type = parameter.schema.type === 'string' ? 'text' : 'number'; - parameterInput.className = "form-control"; - break; - case 'boolean': - parameterInput = document.createElement('input'); - parameterInput.type = 'checkbox'; - break; - case 'array': - case 'object': - parameterInput = document.createElement('textarea'); - parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}`; - parameterInput.className = "form-control"; - break; - case 'enum': - parameterInput = document.createElement('select'); - parameterInput.className = "form-control"; - parameter.schema.enum.forEach(option => { - let optionElement = document.createElement('option'); - optionElement.value = option; - optionElement.text = option; - parameterInput.appendChild(optionElement); - }); - break; - default: - parameterInput = document.createElement('input'); - parameterInput.type = 'text'; - parameterInput.className = "form-control"; - } + let parameterInput; + + // check if enum exists in schema + if (parameter.schema.enum) { + // if enum exists, create a select element + parameterInput = document.createElement('select'); + parameterInput.className = "form-control"; + + // iterate over each enum value and create an option for it + parameter.schema.enum.forEach(value => { + let option = document.createElement('option'); + option.value = value; + option.text = value; + parameterInput.appendChild(option); + }); + } else { + // switch-case statement for handling non-enum types + switch (parameter.schema.type) { + case 'string': + if (parameter.schema.format === 'binary') { + // This is a file input + parameterInput = document.createElement('input'); + parameterInput.type = 'file'; + parameterInput.className = "form-control"; + } else { + parameterInput = document.createElement('input'); + parameterInput.type = 'text'; + parameterInput.className = "form-control"; + } + break; + case 'number': + case 'integer': + parameterInput = document.createElement('input'); + parameterInput.type = 'number'; + parameterInput.className = "form-control"; + break; + case 'boolean': + parameterInput = document.createElement('input'); + parameterInput.type = 'checkbox'; + break; + case 'array': + case 'object': + parameterInput = document.createElement('textarea'); + parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}`; + parameterInput.className = "form-control"; + break; + default: + parameterInput = document.createElement('input'); + parameterInput.type = 'text'; + parameterInput.className = "form-control"; + } + } parameterInput.id = parameter.name; if (operationSettings[operation] && operationSettings[operation][parameter.name] !== undefined) { diff --git a/src/main/resources/templates/pipeline.html b/src/main/resources/templates/pipeline.html index dc959a39..1f61008d 100644 --- a/src/main/resources/templates/pipeline.html +++ b/src/main/resources/templates/pipeline.html @@ -3,98 +3,122 @@ th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org"> - - -
-
-
-

-
-
- - - - - - - - - - - - - - - - - - - - - -
-
-
- + + +
+
+
+ +

+
+
+ +
+
+ + +
+ +
+
+ +
+
+
+
+
+ +
+
+
+ + + + + + + +
+
+
+