diff --git a/src/main/java/stirling/software/SPDF/SPdfApplication.java b/src/main/java/stirling/software/SPDF/SPdfApplication.java index e89413bd..402c98fc 100644 --- a/src/main/java/stirling/software/SPDF/SPdfApplication.java +++ b/src/main/java/stirling/software/SPDF/SPdfApplication.java @@ -4,10 +4,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.core.env.Environment; +import org.springframework.scheduling.annotation.EnableScheduling; import jakarta.annotation.PostConstruct; @SpringBootApplication +@EnableScheduling public class SPdfApplication { @Autowired diff --git a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java index 5a74e1a5..d19a24b6 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java @@ -85,7 +85,7 @@ public class ConvertImgPDFController { @PostMapping(consumes = "multipart/form-data", value = "/img-to-pdf") @Operation(summary = "Convert images to a PDF file", - description = "This endpoint converts one or more images to a PDF file. Users can specify whether to stretch the images to fit the PDF page, and whether to automatically rotate the images. Input:Image Output:PDF Type:MISO") + description = "This endpoint converts one or more images to a PDF file. Users can specify whether to stretch the images to fit the PDF page, and whether to automatically rotate the images. Input:Image Output:PDF Type:SISO?") public ResponseEntity convertToPdf( @RequestPart(required = true, value = "fileInput") @Parameter(description = "The input images to be converted to a PDF file") diff --git a/src/main/java/stirling/software/SPDF/controller/api/pipeline/Controller.java b/src/main/java/stirling/software/SPDF/controller/api/pipeline/Controller.java index a8cad084..d0325450 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/pipeline/Controller.java +++ b/src/main/java/stirling/software/SPDF/controller/api/pipeline/Controller.java @@ -61,10 +61,22 @@ public class Controller { final String watchedFoldersDir = "watchedFolders/"; @Scheduled(fixedRate = 5000) public void scanFolders() { - try (Stream paths = Files.walk(Paths.get(watchedFoldersDir))) { + Path watchedFolderPath = Paths.get(watchedFoldersDir); + if (!Files.exists(watchedFolderPath)) { + try { + Files.createDirectories(watchedFolderPath); + } catch (IOException e) { + e.printStackTrace(); + return; + } + } + + try (Stream paths = Files.walk(watchedFolderPath)) { paths.filter(Files::isDirectory).forEach(t -> { try { - handleDirectory(t); + if (!t.equals(watchedFolderPath) && !t.endsWith("processing")) { + handleDirectory(t); + } } catch (Exception e) { e.printStackTrace(); } @@ -76,6 +88,11 @@ public class Controller { private void handleDirectory(Path dir) throws Exception { Path jsonFile = dir.resolve(jsonFileName); + Path processingDir = dir.resolve("processing"); // Directory to move files during processing + if (!Files.exists(processingDir)) { + Files.createDirectory(processingDir); + } + if (Files.exists(jsonFile)) { // Read JSON file String jsonString; @@ -90,6 +107,10 @@ public class Controller { PipelineConfig config; try { config = objectMapper.readValue(jsonString, PipelineConfig.class); + // Assuming your PipelineConfig class has getters for all necessary fields, you can perform checks here + if (config.getOperations() == null || config.getOutputDir() == null || config.getName() == null) { + throw new IOException("Invalid JSON format"); + } } catch (IOException e) { e.printStackTrace(); return; @@ -114,10 +135,16 @@ public class Controller { // If fileInput contains a path, process only this file files = new File[]{new File(fileInput)}; } - - // Call handleData for each operation + + // Prepare the files for processing + File[] filesToProcess = files.clone(); + for (File file : filesToProcess) { + Files.move(file.toPath(), processingDir.resolve(file.getName())); + } + + // Process the files try { - List resources = handleFiles(files, jsonString); + List resources = handleFiles(filesToProcess, jsonString); // Move resultant files and rename them as per config in JSON file for (Resource resource : resources) { @@ -131,8 +158,17 @@ public class Controller { Files.move(resource.getFile().toPath(), Paths.get(config.getOutputDir(), outputFileName)); } - } catch (IOException e) { - e.printStackTrace(); + + // If successful, delete the original files + for (File file : filesToProcess) { + Files.deleteIfExists(processingDir.resolve(file.getName())); + } + } catch (Exception e) { + // If an error occurs, move the original files back + for (File file : filesToProcess) { + Files.move(processingDir.resolve(file.getName()), file.toPath()); + } + throw e; } } } @@ -140,6 +176,7 @@ public class Controller { + List processFiles(List outputFiles, String jsonString) throws Exception{ ObjectMapper mapper = new ObjectMapper(); JsonNode jsonNode = mapper.readTree(jsonString); diff --git a/src/main/resources/static/js/pipeline.js b/src/main/resources/static/js/pipeline.js index aa03ff23..d92fd220 100644 --- a/src/main/resources/static/js/pipeline.js +++ b/src/main/resources/static/js/pipeline.js @@ -120,6 +120,8 @@ let operationSettings = {}; fetch('v3/api-docs') .then(response => response.json()) .then(data => { + + apiDocs = data.paths; let operationsDropdown = document.getElementById('operationsDropdown'); const ignoreOperations = ["/handleData", "operationToIgnore"]; // Add the operations you want to ignore here @@ -130,7 +132,7 @@ fetch('v3/api-docs') // Group operations by tags Object.keys(data.paths).forEach(operationPath => { let operation = data.paths[operationPath].post; - if (operation && !ignoreOperations.includes(operationPath)) { + if (operation && !ignoreOperations.includes(operationPath) && !operation.description.includes("Type:MISO")) { let operationTag = operation.tags[0]; // This assumes each operation has exactly one tag if (!operationsByTag[operationTag]) { operationsByTag[operationTag] = []; @@ -168,17 +170,21 @@ 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); + + listItem.innerHTML = ` -
-
${selectedOperation}
-
- - - - -
-
- `; +
+
${selectedOperation}
+
+ + + + +
+
+ `; pipelineList.appendChild(listItem);