mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2024-12-21 19:08:24 +01:00
fixes
This commit is contained in:
parent
aed48ffc93
commit
420e4b6766
@ -0,0 +1,212 @@
|
|||||||
|
package stirling.software.SPDF.controller.api.pipeline;
|
||||||
|
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.http.*;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class Controller {
|
||||||
|
|
||||||
|
@PostMapping("/handleData")
|
||||||
|
public ResponseEntity<byte[]> handleData(@RequestPart("fileInput") MultipartFile[] files,
|
||||||
|
@RequestParam("json") String jsonString) {
|
||||||
|
try {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
JsonNode jsonNode = mapper.readTree(jsonString);
|
||||||
|
|
||||||
|
JsonNode pipelineNode = jsonNode.get("pipeline");
|
||||||
|
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
|
||||||
|
PrintStream logPrintStream = new PrintStream(logStream);
|
||||||
|
|
||||||
|
boolean hasErrors = false;
|
||||||
|
List<Resource> outputFiles = new ArrayList<>();
|
||||||
|
|
||||||
|
for (MultipartFile file : files) {
|
||||||
|
Resource fileResource = new ByteArrayResource(file.getBytes()) {
|
||||||
|
@Override
|
||||||
|
public String getFilename() {
|
||||||
|
return file.getOriginalFilename();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
outputFiles.add(fileResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (JsonNode operationNode : pipelineNode) {
|
||||||
|
String operation = operationNode.get("operation").asText();
|
||||||
|
JsonNode parametersNode = operationNode.get("parameters");
|
||||||
|
String inputFileExtension = "";
|
||||||
|
if(operationNode.has("inputFileType")) {
|
||||||
|
inputFileExtension = operationNode.get("inputFileType").asText();
|
||||||
|
} else {
|
||||||
|
inputFileExtension=".pdf";
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Resource> newOutputFiles = new ArrayList<>();
|
||||||
|
boolean hasInputFileType = false;
|
||||||
|
|
||||||
|
for (Resource file : outputFiles) {
|
||||||
|
if (file.getFilename().endsWith(inputFileExtension)) {
|
||||||
|
hasInputFileType = true;
|
||||||
|
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
|
||||||
|
body.add("fileInput", file);
|
||||||
|
|
||||||
|
Iterator<Map.Entry<String, JsonNode>> parameters = parametersNode.fields();
|
||||||
|
while (parameters.hasNext()) {
|
||||||
|
Map.Entry<String, JsonNode> parameter = parameters.next();
|
||||||
|
body.add(parameter.getKey(), parameter.getValue().asText());
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||||
|
|
||||||
|
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);
|
||||||
|
|
||||||
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
|
String url = "http://localhost:8080/" + operation;
|
||||||
|
|
||||||
|
ResponseEntity<byte[]> response = restTemplate.exchange(url, HttpMethod.POST, entity, byte[].class);
|
||||||
|
|
||||||
|
if (!response.getStatusCode().equals(HttpStatus.OK)) {
|
||||||
|
logPrintStream.println("Error: " + response.getBody());
|
||||||
|
hasErrors = true;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasInputFileType) {
|
||||||
|
logPrintStream.println("No files with extension " + inputFileExtension + " found for operation " + operation);
|
||||||
|
hasErrors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputFiles = newOutputFiles;
|
||||||
|
}
|
||||||
|
logPrintStream.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (outputFiles.size() == 1) {
|
||||||
|
// If there is only one file, return it directly
|
||||||
|
Resource singleFile = outputFiles.get(0);
|
||||||
|
InputStream is = singleFile.getInputStream();
|
||||||
|
byte[] bytes = new byte[(int)singleFile.contentLength()];
|
||||||
|
is.read(bytes);
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
return WebResponseUtils.bytesToWebResponse(bytes, singleFile.getFilename(), MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a ByteArrayOutputStream to hold the zip
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
ZipOutputStream zipOut = new ZipOutputStream(baos);
|
||||||
|
|
||||||
|
// Loop through each file and add it to the zip
|
||||||
|
for (Resource file : outputFiles) {
|
||||||
|
ZipEntry zipEntry = new ZipEntry(file.getFilename());
|
||||||
|
zipOut.putNextEntry(zipEntry);
|
||||||
|
|
||||||
|
// Read the file into a byte array
|
||||||
|
InputStream is = file.getInputStream();
|
||||||
|
byte[] bytes = new byte[(int)file.contentLength()];
|
||||||
|
is.read(bytes);
|
||||||
|
|
||||||
|
// Write the bytes of the file to the zip
|
||||||
|
zipOut.write(bytes, 0, bytes.length);
|
||||||
|
zipOut.closeEntry();
|
||||||
|
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
zipOut.close();
|
||||||
|
|
||||||
|
return WebResponseUtils.boasToWebResponse(baos, "output.zip", MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isZip(byte[] data) {
|
||||||
|
if (data == null || data.length < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the first four bytes of the data against the standard zip magic number
|
||||||
|
return data[0] == 0x50 && data[1] == 0x4B && data[2] == 0x03 && data[3] == 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Resource> unzip(byte[] data) throws IOException {
|
||||||
|
List<Resource> unzippedFiles = new ArrayList<>();
|
||||||
|
|
||||||
|
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
||||||
|
ZipInputStream zis = new ZipInputStream(bais)) {
|
||||||
|
|
||||||
|
ZipEntry entry;
|
||||||
|
while ((entry = zis.getNextEntry()) != null) {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int count;
|
||||||
|
|
||||||
|
while ((count = zis.read(buffer)) != -1) {
|
||||||
|
baos.write(buffer, 0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String filename = entry.getName();
|
||||||
|
Resource fileResource = new ByteArrayResource(baos.toByteArray()) {
|
||||||
|
@Override
|
||||||
|
public String getFilename() {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the unzipped file is a zip file, unzip it
|
||||||
|
if (isZip(baos.toByteArray())) {
|
||||||
|
unzippedFiles.addAll(unzip(baos.toByteArray()));
|
||||||
|
} else {
|
||||||
|
unzippedFiles.add(fileResource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return unzippedFiles;
|
||||||
|
}
|
||||||
|
}
|
@ -50,6 +50,11 @@
|
|||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<input type="file" id="fileInput" multiple>
|
||||||
|
|
||||||
|
<button class="btn btn-primary" id="submitConfigBtn">Submit</button>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- pipelineSettings modal -->
|
<!-- pipelineSettings modal -->
|
||||||
@ -99,6 +104,61 @@
|
|||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
document.getElementById('submitConfigBtn').addEventListener('click', function() {
|
||||||
|
// Get the selected configuration
|
||||||
|
let selectedOperation = document.getElementById('operationsDropdown').value;
|
||||||
|
let parameters = operationSettings[selectedOperation] || {};
|
||||||
|
|
||||||
|
// Create the pipelineConfig object
|
||||||
|
let pipelineConfig = {
|
||||||
|
"name": "uniquePipelineName",
|
||||||
|
"pipeline": [{
|
||||||
|
"operation": selectedOperation,
|
||||||
|
"parameters": parameters
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
let pipelineConfigJson = JSON.stringify(pipelineConfig, null, 2);
|
||||||
|
|
||||||
|
// Create new FormData instance
|
||||||
|
let formData = new FormData();
|
||||||
|
|
||||||
|
// Get the selected files from the file input
|
||||||
|
let fileInput = document.getElementById('fileInput');
|
||||||
|
let files = fileInput.files;
|
||||||
|
|
||||||
|
// Add files to formData
|
||||||
|
for(let i = 0; i < files.length; i++) {
|
||||||
|
console.log("files[i]",files[i].name);
|
||||||
|
formData.append('fileInput', files[i], files[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the JSON string to formData
|
||||||
|
console.log("pipelineConfigJson",pipelineConfigJson);
|
||||||
|
formData.append('json', pipelineConfigJson);
|
||||||
|
console.log("formData",formData);
|
||||||
|
// Make a POST request to the server
|
||||||
|
fetch('/handleData', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(response => response.blob())
|
||||||
|
.then(blob => {
|
||||||
|
// Create a link element
|
||||||
|
let url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'outputfile'; // or you can name your output file here
|
||||||
|
document.body.appendChild(a); // Required for Firefox
|
||||||
|
a.click();
|
||||||
|
a.remove(); // After triggering download we remove the element
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let apiDocs = {};
|
let apiDocs = {};
|
||||||
|
|
||||||
@ -308,6 +368,11 @@
|
|||||||
"pipeline": []
|
"pipeline": []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (pipelineList[pipelineList.length - 1].querySelector('.operationName').textContent !== '/add-password') {
|
||||||
|
alert('The "add-password" operation should be at the end of the operations sequence. Please adjust the operations order.');
|
||||||
|
return; // Stop the function execution
|
||||||
|
}
|
||||||
|
|
||||||
for(let i=0; i<pipelineList.length; i++) {
|
for(let i=0; i<pipelineList.length; i++) {
|
||||||
let operationName = pipelineList[i].querySelector('.operationName').textContent;
|
let operationName = pipelineList[i].querySelector('.operationName').textContent;
|
||||||
let parameters = operationSettings[operationName] || {}; // Retrieve saved parameters for this operation
|
let parameters = operationSettings[operationName] || {}; // Retrieve saved parameters for this operation
|
||||||
|
Loading…
Reference in New Issue
Block a user