This commit is contained in:
Anthony Stirling 2023-06-26 18:23:06 +01:00
parent 3377af1305
commit 43b0e25bdb
5 changed files with 229 additions and 15 deletions

View file

@ -0,0 +1,73 @@
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.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 ResponseEntity<byte[]> 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 ResponseEntity<byte[]> pageCount(
@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 = "Page COunt", required = true) String pageCount,
@Parameter(description = "Comparison type, accepts Greater, Equal, Less than", required = false) String comparitor)
throws IOException, InterruptedException {
return null;
}
@PostMapping(consumes = "multipart/form-data", value = "/page-size")
@Operation(summary = "Checks if a PDF is a set size", description = "Input:PDF Output:Boolean Type:SISO")
public ResponseEntity<byte[]> pageSize(
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to be converted to a PDF/A file", required = true) MultipartFile inputFile)
throws IOException, InterruptedException {
return null;
}
@PostMapping(consumes = "multipart/form-data", value = "/page-rotation")
@Operation(summary = "Checks if a PDF is a set rotation", description = "Input:PDF Output:Boolean Type:SISO")
public ResponseEntity<byte[]> pageRotation(
@RequestPart(required = true, value = "fileInput") @Parameter(description = "The input PDF file to be converted to a PDF/A file", required = true) MultipartFile inputFile)
throws IOException, InterruptedException {
return null;
}
}

View file

@ -42,16 +42,51 @@ public class PdfUtils {
private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class);
public boolean hasImageInFile(PDDocument pdfDocument, String text, String pagesToCheck) throws IOException {
PDFTextStripper textStripper = new PDFTextStripper();
String pdfText = "";
if(pagesToCheck == null || pagesToCheck.equals("all")) {
pdfText = textStripper.getText(pdfDocument);
} else {
// remove whitespaces
pagesToCheck = pagesToCheck.replaceAll("\\s+", "");
String[] splitPoints = pagesToCheck.split(",");
for (String splitPoint : splitPoints) {
if (splitPoint.contains("-")) {
// Handle page ranges
String[] range = splitPoint.split("-");
int startPage = Integer.parseInt(range[0]);
int endPage = Integer.parseInt(range[1]);
for (int i = startPage; i <= endPage; i++) {
textStripper.setStartPage(i);
textStripper.setEndPage(i);
pdfText += textStripper.getText(pdfDocument);
}
} else {
// Handle individual page
int page = Integer.parseInt(splitPoint);
textStripper.setStartPage(page);
textStripper.setEndPage(page);
pdfText += textStripper.getText(pdfDocument);
}
}
}
pdfDocument.close();
return pdfText.contains(text);
}
public static boolean hasImagesOnPage(PDPage page) throws IOException {
ImageFinder imageFinder = new ImageFinder(page);
imageFinder.processPage(page);
return imageFinder.hasImages();
}
public static boolean hasTextOnPage(PdfPage page, String phrase) throws IOException {
String text = PdfTextExtractor.getTextFromPage(page, new SimpleTextExtractionStrategy());
return text.contains(phrase);
}
public static boolean hasText(PDDocument document, String phrase) throws IOException {
PDFTextStripper pdfStripper = new PDFTextStripper();
String text = pdfStripper.getText(document);
@ -59,6 +94,86 @@ public class PdfUtils {
}
public boolean containsTextInFile(PDDocument pdfDocument, String text, String pagesToCheck) throws IOException {
PDFTextStripper textStripper = new PDFTextStripper();
String pdfText = "";
if(pagesToCheck == null || pagesToCheck.equals("all")) {
pdfText = textStripper.getText(pdfDocument);
} else {
// remove whitespaces
pagesToCheck = pagesToCheck.replaceAll("\\s+", "");
String[] splitPoints = pagesToCheck.split(",");
for (String splitPoint : splitPoints) {
if (splitPoint.contains("-")) {
// Handle page ranges
String[] range = splitPoint.split("-");
int startPage = Integer.parseInt(range[0]);
int endPage = Integer.parseInt(range[1]);
for (int i = startPage; i <= endPage; i++) {
textStripper.setStartPage(i);
textStripper.setEndPage(i);
pdfText += textStripper.getText(pdfDocument);
}
} else {
// Handle individual page
int page = Integer.parseInt(splitPoint);
textStripper.setStartPage(page);
textStripper.setEndPage(page);
pdfText += textStripper.getText(pdfDocument);
}
}
}
pdfDocument.close();
return pdfText.contains(text);
}
public boolean pageCount(PDDocument pdfDocument, int pageCount, String comparator) throws IOException {
int actualPageCount = pdfDocument.getNumberOfPages();
pdfDocument.close();
switch(comparator.toLowerCase()) {
case "greater":
return actualPageCount > pageCount;
case "equal":
return actualPageCount == pageCount;
case "less":
return actualPageCount < pageCount;
default:
throw new IllegalArgumentException("Invalid comparator. Only 'greater', 'equal', and 'less' are supported.");
}
}
public boolean pageSize(PDDocument pdfDocument, String expectedPageSize) throws IOException {
PDPage firstPage = pdfDocument.getPage(0);
PDRectangle mediaBox = firstPage.getMediaBox();
float actualPageWidth = mediaBox.getWidth();
float actualPageHeight = mediaBox.getHeight();
pdfDocument.close();
// Assumes the expectedPageSize is in the format "widthxheight", e.g. "595x842" for A4
String[] dimensions = expectedPageSize.split("x");
float expectedPageWidth = Float.parseFloat(dimensions[0]);
float expectedPageHeight = Float.parseFloat(dimensions[1]);
// Checks if the actual page size matches the expected page size
return actualPageWidth == expectedPageWidth && actualPageHeight == expectedPageHeight;
}
public static byte[] convertFromPdf(byte[] inputStream, String imageType, ImageType colorType, boolean singleImage, int DPI, String filename) throws IOException, Exception {
try (PDDocument document = PDDocument.load(new ByteArrayInputStream(inputStream))) {
PDFRenderer pdfRenderer = new PDFRenderer(document);

View file

@ -142,6 +142,8 @@ font=Font
selectFillter=-- Select --
pageNum=Page Number
pipeline.title=Pipeline
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:

View file

@ -120,24 +120,48 @@ let operationSettings = {};
fetch('v3/api-docs')
.then(response => response.json())
.then(data => {
apiDocs = data.paths;
let operationsDropdown = document.getElementById('operationsDropdown');
const ignoreOperations = ["operationToIgnore", "operationToIgnore"]; // Add the operations you want to ignore here
const ignoreOperations = ["/handleData", "operationToIgnore"]; // Add the operations you want to ignore here
operationsDropdown.innerHTML = '';
Object.keys(apiDocs).forEach(operation => {
if (apiDocs[operation].hasOwnProperty('post')&& !ignoreOperations.includes(operation)) {
let option = document.createElement('option');
let operationWithoutSlash = operation.replace(/\//g, ''); // Remove slashes
option.textContent = operationWithoutSlash;
option.value = operation; // Keep the value with slashes for querying
operationsDropdown.appendChild(option);
let operationsByTag = {};
// Group operations by tags
Object.keys(data.paths).forEach(operationPath => {
let operation = data.paths[operationPath].post;
if (operation && !ignoreOperations.includes(operationPath)) {
let operationTag = operation.tags[0]; // This assumes each operation has exactly one tag
if (!operationsByTag[operationTag]) {
operationsByTag[operationTag] = [];
}
operationsByTag[operationTag].push(operationPath);
}
});
// Specify the order of tags
let tagOrder = ["General", "Security", "Convert", "Other", "Filter"];
// Create dropdown options
tagOrder.forEach(tag => {
if (operationsByTag[tag]) {
let group = document.createElement('optgroup');
group.label = tag;
operationsByTag[tag].forEach(operationPath => {
let option = document.createElement('option');
let operationWithoutSlash = operationPath.replace(/\//g, ''); // Remove slashes
option.textContent = operationWithoutSlash;
option.value = operationPath; // Keep the value with slashes for querying
group.appendChild(option);
});
operationsDropdown.appendChild(group);
}
});
});
document.getElementById('addOperationBtn').addEventListener('click', function() {
let selectedOperation = document.getElementById('operationsDropdown').value;
let pipelineList = document.getElementById('pipelineList');

View file

@ -3,7 +3,7 @@
th:lang-direction="#{language.direction}"
xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/common :: head(title=#{merge.title})}"></th:block>
<th:block th:insert="~{fragments/common :: head(title=#{pipeline.title})}"></th:block>
<body>
<div id="page-container">
<div id="content-wrap">