This commit is contained in:
Anthony Stirling 2025-06-30 22:38:51 +01:00
parent 617ab2ad79
commit 5591a655d0
4 changed files with 43 additions and 45 deletions

View File

@ -47,6 +47,7 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.EndpointConfiguration;
@ -61,18 +62,18 @@ import stirling.software.common.util.WebResponseUtils;
@RequestMapping("/api/v1/misc")
@Slf4j
@Tag(name = "Misc", description = "Miscellaneous APIs")
@RequiredArgsConstructor
public class CompressController {
private final CustomPDFDocumentFactory pdfDocumentFactory;
private final boolean qpdfEnabled;
private final boolean ghostscriptEnabled;
public CompressController(
CustomPDFDocumentFactory pdfDocumentFactory,
EndpointConfiguration endpointConfiguration) {
this.pdfDocumentFactory = pdfDocumentFactory;
this.qpdfEnabled = endpointConfiguration.isGroupEnabled("qpdf");
this.ghostscriptEnabled = endpointConfiguration.isGroupEnabled("Ghostscript");
private final EndpointConfiguration endpointConfiguration;
private boolean isQpdfEnabled() {
return endpointConfiguration.isGroupEnabled("qpdf");
}
private boolean isGhostscriptEnabled() {
return endpointConfiguration.isGroupEnabled("Ghostscript");
}
@Data
@ -707,7 +708,7 @@ public class CompressController {
boolean ghostscriptSuccess = false;
// Try Ghostscript first if available - for ANY compression level
if (ghostscriptEnabled) {
if (isGhostscriptEnabled()) {
try {
applyGhostscriptCompression(
request, optimizeLevel, currentFile, tempFiles);
@ -719,7 +720,7 @@ public class CompressController {
}
// Fallback to QPDF if Ghostscript failed or not available (levels 1-3 only)
if (!ghostscriptSuccess && qpdfEnabled && optimizeLevel <= 3) {
if (!ghostscriptSuccess && isQpdfEnabled() && optimizeLevel <= 3) {
try {
applyQpdfCompression(request, optimizeLevel, currentFile, tempFiles);
log.info("QPDF compression applied successfully");
@ -728,7 +729,7 @@ public class CompressController {
}
}
if (!ghostscriptSuccess && !qpdfEnabled) {
if (!ghostscriptSuccess && !isQpdfEnabled()) {
log.info(
"No external compression tools available, using image compression only");
}

View File

@ -27,6 +27,7 @@ import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.EndpointConfiguration;
@ -44,24 +45,20 @@ import stirling.software.common.util.WebResponseUtils;
@RequestMapping("/api/v1/misc")
@Tag(name = "Misc", description = "Miscellaneous APIs")
@Slf4j
@RequiredArgsConstructor
public class OCRController {
private final ApplicationProperties applicationProperties;
private final CustomPDFDocumentFactory pdfDocumentFactory;
private final TempFileManager tempFileManager;
private final boolean ocrMyPdfEnabled;
private final boolean tesseractEnabled;
public OCRController(
ApplicationProperties applicationProperties,
CustomPDFDocumentFactory pdfDocumentFactory,
TempFileManager tempFileManager,
EndpointConfiguration endpointConfiguration) {
this.applicationProperties = applicationProperties;
this.pdfDocumentFactory = pdfDocumentFactory;
this.tempFileManager = tempFileManager;
this.ocrMyPdfEnabled = endpointConfiguration.isGroupEnabled("OCRmyPDF");
this.tesseractEnabled = endpointConfiguration.isGroupEnabled("tesseract");
private final EndpointConfiguration endpointConfiguration;
private boolean isOcrMyPdfEnabled() {
return endpointConfiguration.isGroupEnabled("OCRmyPDF");
}
private boolean isTesseractEnabled() {
return endpointConfiguration.isGroupEnabled("tesseract");
}
/** Gets the list of available Tesseract languages from the tessdata directory */
@ -127,7 +124,7 @@ public class OCRController {
try {
// Use OCRmyPDF if available (no fallback - error if it fails)
if (ocrMyPdfEnabled) {
if (isOcrMyPdfEnabled()) {
if (sidecar != null && sidecar) {
sidecarTextFile = new TempFile(tempFileManager, ".txt");
}
@ -147,7 +144,7 @@ public class OCRController {
log.info("OCRmyPDF processing completed successfully");
}
// Use Tesseract only if OCRmyPDF is not available
else if (tesseractEnabled) {
else if (isTesseractEnabled()) {
processWithTesseract(
selectedLanguages,
ocrType,

View File

@ -14,7 +14,8 @@ import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.EndpointConfiguration;
import stirling.software.common.model.api.PDFFile;
import stirling.software.common.service.CustomPDFDocumentFactory;
@ -27,21 +28,20 @@ import stirling.software.common.util.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/misc")
@Tag(name = "Misc", description = "Miscellaneous APIs")
@Slf4j
@RequiredArgsConstructor
public class RepairController {
private final CustomPDFDocumentFactory pdfDocumentFactory;
private final TempFileManager tempFileManager;
private final boolean ghostscriptEnabled;
private final boolean qpdfEnabled;
public RepairController(
CustomPDFDocumentFactory pdfDocumentFactory,
TempFileManager tempFileManager,
EndpointConfiguration endpointConfiguration) {
this.pdfDocumentFactory = pdfDocumentFactory;
this.tempFileManager = tempFileManager;
this.ghostscriptEnabled = endpointConfiguration.isGroupEnabled("Ghostscript");
this.qpdfEnabled = endpointConfiguration.isGroupEnabled("qpdf");
private final EndpointConfiguration endpointConfiguration;
private boolean isGhostscriptEnabled() {
return endpointConfiguration.isGroupEnabled("Ghostscript");
}
private boolean isQpdfEnabled() {
return endpointConfiguration.isGroupEnabled("qpdf");
}
@PostMapping(consumes = "multipart/form-data", value = "/repair")
@ -65,7 +65,7 @@ public class RepairController {
boolean repairSuccess = false;
// Try Ghostscript first if available
if (ghostscriptEnabled) {
if (isGhostscriptEnabled()) {
try {
List<String> gsCommand = new ArrayList<>();
gsCommand.add("gs");
@ -83,13 +83,13 @@ public class RepairController {
}
} catch (Exception e) {
// Log and continue to QPDF fallback
System.out.println(
"Ghostscript repair failed, trying QPDF fallback: " + e.getMessage());
log.warn(
"Ghostscript repair failed, trying QPDF fallback: ", e);
}
}
// Fallback to QPDF if Ghostscript failed or not available
if (!repairSuccess && qpdfEnabled) {
if (!repairSuccess && isQpdfEnabled()) {
List<String> qpdfCommand = new ArrayList<>();
qpdfCommand.add("qpdf");
qpdfCommand.add("--replace-input"); // Automatically fixes problems it can
@ -107,7 +107,7 @@ public class RepairController {
// Use PDFBox as last resort if no external tools are available
if (!repairSuccess) {
if (!ghostscriptEnabled && !qpdfEnabled) {
if (!isGhostscriptEnabled() && !isQpdfEnabled()) {
// Basic PDFBox repair - load and save to fix structural issues
try (var document = pdfDocumentFactory.load(tempInputFile.getFile())) {
document.save(tempOutputFile.getFile());

View File

@ -79,7 +79,7 @@
</select>
</div>
<br>
<div class="mb-3" th:if>
<div class="mb-3" th:if="${@endpointConfiguration.isGroupEnabled('OCRmyPDF')}">
<label class="form-label">OCR Options</label>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="sidecar" name="sidecar" value="true">