mirror of
				https://github.com/Frooodle/Stirling-PDF.git
				synced 2025-11-01 01:21:18 +01:00 
			
		
		
		
	modes
This commit is contained in:
		
							parent
							
								
									3377af1305
								
							
						
					
					
						commit
						43b0e25bdb
					
				@ -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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -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:
 | 
			
		||||
 | 
			
		||||
@ -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');
 | 
			
		||||
 | 
			
		||||
@ -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">
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user