# Description This pull request includes several changes aimed at improving the code structure and removing redundant code. The most significant changes involve reordering methods, removing unnecessary annotations, and refactoring constructors to use dependency injection. Autowired now comes via constructor (which also doesn't need autowired annotation as its done by default for configuration) ## Checklist - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have performed a self-review of my own code - [ ] I have attached images of the change if it is UI based - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] If my code has heavily changed functionality I have updated relevant docs on [Stirling-PDFs doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) - [ ] My changes generate no new warnings - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only)
148 lines
6.0 KiB
Java
148 lines
6.0 KiB
Java
package stirling.software.SPDF.config;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.stream.Collectors;
|
|
|
|
import org.springframework.context.annotation.Configuration;
|
|
|
|
import jakarta.annotation.PostConstruct;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
@Configuration
|
|
@Slf4j
|
|
public class ExternalAppDepConfig {
|
|
|
|
private final EndpointConfiguration endpointConfiguration;
|
|
private final Map<String, List<String>> commandToGroupMapping =
|
|
new HashMap<>() {
|
|
|
|
{
|
|
put("soffice", List.of("LibreOffice"));
|
|
put("weasyprint", List.of("Weasyprint"));
|
|
put("pdftohtml", List.of("Pdftohtml"));
|
|
put("unoconv", List.of("Unoconv"));
|
|
put("qpdf", List.of("qpdf"));
|
|
put("tesseract", List.of("tesseract"));
|
|
}
|
|
};
|
|
|
|
public ExternalAppDepConfig(EndpointConfiguration endpointConfiguration) {
|
|
this.endpointConfiguration = endpointConfiguration;
|
|
}
|
|
|
|
private boolean isCommandAvailable(String command) {
|
|
try {
|
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
|
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
|
|
processBuilder.command("where", command);
|
|
} else {
|
|
processBuilder.command("which", command);
|
|
}
|
|
Process process = processBuilder.start();
|
|
int exitCode = process.waitFor();
|
|
return exitCode == 0;
|
|
} catch (Exception e) {
|
|
log.debug("Error checking for command {}: {}", command, e.getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private List<String> getAffectedFeatures(String group) {
|
|
return endpointConfiguration.getEndpointsForGroup(group).stream()
|
|
.map(endpoint -> formatEndpointAsFeature(endpoint))
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
private String formatEndpointAsFeature(String endpoint) {
|
|
// First replace common terms
|
|
String feature = endpoint.replace("-", " ").replace("pdf", "PDF").replace("img", "image");
|
|
// Split into words and capitalize each word
|
|
return Arrays.stream(feature.split("\\s+"))
|
|
.map(word -> capitalizeWord(word))
|
|
.collect(Collectors.joining(" "));
|
|
}
|
|
|
|
private String capitalizeWord(String word) {
|
|
if (word.isEmpty()) {
|
|
return word;
|
|
}
|
|
if ("pdf".equalsIgnoreCase(word)) {
|
|
return "PDF";
|
|
}
|
|
return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
|
|
}
|
|
|
|
private void checkDependencyAndDisableGroup(String command) {
|
|
boolean isAvailable = isCommandAvailable(command);
|
|
if (!isAvailable) {
|
|
List<String> affectedGroups = commandToGroupMapping.get(command);
|
|
if (affectedGroups != null) {
|
|
for (String group : affectedGroups) {
|
|
List<String> affectedFeatures = getAffectedFeatures(group);
|
|
endpointConfiguration.disableGroup(group);
|
|
log.warn(
|
|
"Missing dependency: {} - Disabling group: {} (Affected features: {})",
|
|
command,
|
|
group,
|
|
affectedFeatures != null && !affectedFeatures.isEmpty()
|
|
? String.join(", ", affectedFeatures)
|
|
: "unknown");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@PostConstruct
|
|
public void checkDependencies() {
|
|
// Check core dependencies
|
|
checkDependencyAndDisableGroup("tesseract");
|
|
checkDependencyAndDisableGroup("soffice");
|
|
checkDependencyAndDisableGroup("qpdf");
|
|
checkDependencyAndDisableGroup("weasyprint");
|
|
checkDependencyAndDisableGroup("pdftohtml");
|
|
checkDependencyAndDisableGroup("unoconv");
|
|
// Special handling for Python/OpenCV dependencies
|
|
boolean pythonAvailable = isCommandAvailable("python3") || isCommandAvailable("python");
|
|
if (!pythonAvailable) {
|
|
List<String> pythonFeatures = getAffectedFeatures("Python");
|
|
List<String> openCVFeatures = getAffectedFeatures("OpenCV");
|
|
endpointConfiguration.disableGroup("Python");
|
|
endpointConfiguration.disableGroup("OpenCV");
|
|
log.warn(
|
|
"Missing dependency: Python - Disabling Python features: {} and OpenCV features: {}",
|
|
String.join(", ", pythonFeatures),
|
|
String.join(", ", openCVFeatures));
|
|
} else {
|
|
// If Python is available, check for OpenCV
|
|
try {
|
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
|
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
|
|
processBuilder.command("python", "-c", "import cv2");
|
|
} else {
|
|
processBuilder.command("python3", "-c", "import cv2");
|
|
}
|
|
Process process = processBuilder.start();
|
|
int exitCode = process.waitFor();
|
|
if (exitCode != 0) {
|
|
List<String> openCVFeatures = getAffectedFeatures("OpenCV");
|
|
endpointConfiguration.disableGroup("OpenCV");
|
|
log.warn(
|
|
"OpenCV not available in Python - Disabling OpenCV features: {}",
|
|
String.join(", ", openCVFeatures));
|
|
}
|
|
} catch (Exception e) {
|
|
List<String> openCVFeatures = getAffectedFeatures("OpenCV");
|
|
endpointConfiguration.disableGroup("OpenCV");
|
|
log.warn(
|
|
"Error checking OpenCV: {} - Disabling OpenCV features: {}",
|
|
e.getMessage(),
|
|
String.join(", ", openCVFeatures));
|
|
}
|
|
}
|
|
endpointConfiguration.logDisabledEndpointsSummary();
|
|
}
|
|
}
|