diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6aff3196..9146d798 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,7 +76,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.7" + python-version: "3.12" - name: Pip requirements run: | diff --git a/.github/workflows/multiOSReleases.yml b/.github/workflows/multiOSReleases.yml index cd6206cd..a67b85a0 100644 --- a/.github/workflows/multiOSReleases.yml +++ b/.github/workflows/multiOSReleases.yml @@ -74,7 +74,7 @@ jobs: shell: bash run: | if [ "${{ matrix.os }}" = "windows-latest" ]; then - mv "build/jpackage/Stirling-PDF-${{ steps.versionNumber.outputs.versionNumber }}.exe" "Stirling-PDF-${{ steps.versionNumber.outputs.versionNumber }}-${{ matrix.platform }}.${{ matrix.ext }}" + mv "build/jpackage/Stirling-PDF-${{ steps.versionNumber.outputs.versionNumber }}.exe" "Stirling-PDF-${{ matrix.platform }}-installer.${{ matrix.ext }}" elif [ "${{ matrix.os }}" = "macos-latest" ]; then mv "build/jpackage/Stirling-PDF-${{ steps.versionNumberMac.outputs.versionNumberMac }}.dmg" "Stirling-PDF-${{ steps.versionNumber.outputs.versionNumber }}-${{ matrix.platform }}.${{ matrix.ext }}" else @@ -85,7 +85,12 @@ jobs: - name: Upload Installer Artifact uses: actions/upload-artifact@v4 with: - name: Stirling-PDF-${{ matrix.platform }}-installer.{{ matrix.ext }} - path: Stirling-PDF-${{ steps.versionNumber.outputs.versionNumber }}-${{ matrix.platform }}.${{ matrix.ext }} + name: Stirling-PDF-${{ matrix.platform }}-installer.${{ matrix.ext }} + path: Stirling-PDF-${{ matrix.platform }}-installer.${{ matrix.ext }} retention-days: 1 - if-no-files-found: error \ No newline at end of file + if-no-files-found: error + + - name: Upload binaries to release + uses: softprops/action-gh-release@v2 + with: + files: ./Stirling-PDF-${{ matrix.platform }}-installer.${{ matrix.ext }} diff --git a/.github/workflows/releaseArtifacts.yml b/.github/workflows/releaseArtifacts.yml index 851fd6ca..a2bf7d4f 100644 --- a/.github/workflows/releaseArtifacts.yml +++ b/.github/workflows/releaseArtifacts.yml @@ -59,13 +59,13 @@ jobs: files: ./build/launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe - name: Rename jar binaries - run: cp ./build/libs/Stirling-PDF-${{ steps.versionNumber.outputs.versionNumber }}.jar ./build/libs/Stirling-PDF-Server${{ matrix.file_suffix }}.jar + run: cp ./build/libs/Stirling-PDF-${{ steps.versionNumber.outputs.versionNumber }}.jar ./build/libs/Stirling-PDF${{ matrix.file_suffix }}.jar - name: Upload Assets jar binaries uses: actions/upload-artifact@v4 with: - path: ./build/libs/Stirling-PDF-Server${{ matrix.file_suffix }}.jar - name: Stirling-PDF-Server${{ matrix.file_suffix }}.jar + path: ./build/libs/Stirling-PDF${{ matrix.file_suffix }}.jar + name: Stirling-PDF${{ matrix.file_suffix }}.jar overwrite: true retention-days: 1 if-no-files-found: error @@ -73,7 +73,7 @@ jobs: - name: Upload jar binaries to release uses: softprops/action-gh-release@v2 with: - files: ./build/libs/Stirling-PDF-Server${{ matrix.file_suffix }}.jar + files: ./build/libs/Stirling-PDF${{ matrix.file_suffix }}.jar push-ui: diff --git a/.vscode/settings.json b/.vscode/settings.json index b0d31dae..c8ef9888 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -49,5 +49,7 @@ "editor.indentSize": "tabSize", "editor.stickyScroll.enabled": false, "editor.minimap.enabled": false, - "editor.formatOnSave": true + "editor.formatOnSave": true, + "java.format.settings.google.mode": "jar-file", + "java.format.settings.google.extra": "--aosp --skip-sorting-imports" } diff --git a/DATABASE.md b/DATABASE.md index e8e0c838..c37c598b 100644 --- a/DATABASE.md +++ b/DATABASE.md @@ -1,12 +1,5 @@ # New Database Backup and Import Functionality -> [!IMPORTANT] -> **Full activation will take place on approximately January 5th, 2025!** - -Why is the waiting time six months? - -There are users who only install updates sporadically; if they skip the preparation, it can/will lead to data loss in the database. - ## Functionality Overview The newly introduced feature enhances the application with robust database backup and import capabilities. This feature is designed to ensure data integrity and provide a straightforward way to manage database backups. Here's how it works: diff --git a/README.md b/README.md index 5bf81477..1a7fb747 100644 --- a/README.md +++ b/README.md @@ -192,32 +192,32 @@ Stirling-PDF currently supports 38 languages! | Language | Progress | | -------------------------------------------- | -------------------------------------- | | Arabic (العربية) (ar_AR) | ![94%](https://geps.dev/progress/94) | -| Azerbaijani (Azərbaycan Dili) (az_AZ) | ![93%](https://geps.dev/progress/93) | +| Azerbaijani (Azərbaycan Dili) (az_AZ) | ![92%](https://geps.dev/progress/92) | | Basque (Euskara) (eu_ES) | ![53%](https://geps.dev/progress/53) | -| Bulgarian (Български) (bg_BG) | ![90%](https://geps.dev/progress/90) | +| Bulgarian (Български) (bg_BG) | ![89%](https://geps.dev/progress/89) | | Catalan (Català) (ca_CA) | ![84%](https://geps.dev/progress/84) | | Croatian (Hrvatski) (hr_HR) | ![91%](https://geps.dev/progress/91) | -| Czech (Česky) (cs_CZ) | ![91%](https://geps.dev/progress/91) | -| Danish (Dansk) (da_DK) | ![90%](https://geps.dev/progress/90) | +| Czech (Česky) (cs_CZ) | ![90%](https://geps.dev/progress/90) | +| Danish (Dansk) (da_DK) | ![89%](https://geps.dev/progress/89) | | Dutch (Nederlands) (nl_NL) | ![89%](https://geps.dev/progress/89) | | English (English) (en_GB) | ![100%](https://geps.dev/progress/100) | | English (US) (en_US) | ![100%](https://geps.dev/progress/100) | | French (Français) (fr_FR) | ![92%](https://geps.dev/progress/92) | -| German (Deutsch) (de_DE) | ![99%](https://geps.dev/progress/99) | +| German (Deutsch) (de_DE) | ![100%](https://geps.dev/progress/100) | | Greek (Ελληνικά) (el_GR) | ![90%](https://geps.dev/progress/90) | | Hindi (हिंदी) (hi_IN) | ![88%](https://geps.dev/progress/88) | | Hungarian (Magyar) (hu_HU) | ![91%](https://geps.dev/progress/91) | -| Indonesian (Bahasa Indonesia) (id_ID) | ![91%](https://geps.dev/progress/91) | -| Irish (Gaeilge) (ga_IE) | ![83%](https://geps.dev/progress/83) | +| Indonesian (Bahasa Indonesia) (id_ID) | ![90%](https://geps.dev/progress/90) | +| Irish (Gaeilge) (ga_IE) | ![82%](https://geps.dev/progress/82) | | Italian (Italiano) (it_IT) | ![99%](https://geps.dev/progress/99) | | Japanese (日本語) (ja_JP) | ![93%](https://geps.dev/progress/93) | | Korean (한국어) (ko_KR) | ![89%](https://geps.dev/progress/89) | | Norwegian (Norsk) (no_NB) | ![82%](https://geps.dev/progress/82) | | Persian (فارسی) (fa_IR) | ![99%](https://geps.dev/progress/99) | | Polish (Polski) (pl_PL) | ![90%](https://geps.dev/progress/90) | -| Portuguese (Português) (pt_PT) | ![91%](https://geps.dev/progress/91) | +| Portuguese (Português) (pt_PT) | ![90%](https://geps.dev/progress/90) | | Portuguese Brazilian (Português) (pt_BR) | ![98%](https://geps.dev/progress/98) | -| Romanian (Română) (ro_RO) | ![85%](https://geps.dev/progress/85) | +| Romanian (Română) (ro_RO) | ![84%](https://geps.dev/progress/84) | | Russian (Русский) (ru_RU) | ![90%](https://geps.dev/progress/90) | | Serbian Latin alphabet (Srpski) (sr_LATN_RS) | ![67%](https://geps.dev/progress/67) | | Simplified Chinese (简体中文) (zh_CN) | ![93%](https://geps.dev/progress/93) | diff --git a/build.gradle b/build.gradle index 6a0862a8..fde7fb36 100644 --- a/build.gradle +++ b/build.gradle @@ -22,12 +22,12 @@ ext { imageioVersion = "3.12.0" lombokVersion = "1.18.36" bouncycastleVersion = "1.79" - springSecuritySamlVersion = "6.4.1" - openSamlVersion = "4.3.2" + springSecuritySamlVersion = "6.4.2" + openSamlVersion = "4.3.2" } group = "stirling.software" -version = "0.36.1" +version = "0.36.4" java { @@ -44,7 +44,7 @@ repositories { } maven { url "https://build.shibboleth.net/maven/releases" } maven { url "https://maven.pkg.github.com/jcefmaven/jcefmaven" } - + } licenseReport { @@ -68,12 +68,12 @@ sourceSets { exclude "stirling/software/SPDF/model/User.java" exclude "stirling/software/SPDF/repository/**" } - + if (System.getenv("STIRLING_PDF_DESKTOP_UI") == "false") { exclude "stirling/software/SPDF/UI/impl/**" } - - + + } } } @@ -104,7 +104,7 @@ jpackage { icon = "src/main/resources/static/favicon.ico" - + // JVM Options javaOptions = [ @@ -115,12 +115,12 @@ jpackage { "--add-opens", "java.base/java.lang=ALL-UNNAMED", "--add-opens", "java.desktop/java.awt.event=ALL-UNNAMED", "--add-opens", "java.desktop/sun.awt=ALL-UNNAMED" - + ] verbose = true - + destination = "${projectDir}/build/jpackage" // Windows-specific configuration @@ -150,16 +150,16 @@ jpackage { macAppCategory = "public.app-category.productivity" macSign = false // Enable signing macAppStore = false // Not targeting App Store initially - + //installDir = "Applications" - + // Add license and other documentation to DMG /*macDmgContent = [ "README.md", "LICENSE", "CHANGELOG.md" ]*/ - + // Enable Mac-specific entitlements //macEntitlements = "entitlements.plist" // You'll need to create this file } @@ -169,7 +169,7 @@ jpackage { appVersion = project.version icon = "src/main/resources/static/favicon.png" type = "deb" // Can also use "rpm" for Red Hat-based systems - + // Debian package configuration //linuxPackageName = "stirlingpdf" linuxDebMaintainer = "support@stirlingpdf.com" @@ -177,9 +177,9 @@ jpackage { linuxAppCategory = "Office" linuxAppRelease = "1" linuxPackageDeps = true - + installDir = "/opt/Stirling-PDF" - + // RPM-specific settings //linuxRpmLicenseType = "MIT" } @@ -212,7 +212,7 @@ launch4j { icon = "${projectDir}/src/main/resources/static/favicon.ico" outfile="Stirling-PDF.exe" - + if(System.getenv("STIRLING_PDF_DESKTOP_UI") == 'true') { headerType = "gui" } else { @@ -222,15 +222,15 @@ launch4j { errTitle="Encountered error, Do you have Java 21?" downloadUrl="https://download.oracle.com/java/21/latest/jdk-21_windows-x64_bin.exe" - + if(System.getenv("STIRLING_PDF_DESKTOP_UI") == 'true') { variables=["BROWSER_OPEN=true", "STIRLING_PDF_DESKTOP_UI=true"] } else { variables=["BROWSER_OPEN=true"] } - - - + + + jreMinVersion="17" mutexName="Stirling-PDF" @@ -247,7 +247,7 @@ spotless { java { target project.fileTree('src/main/java') - googleJavaFormat("1.22.0").aosp().reorderImports(false) + googleJavaFormat("1.25.2").aosp().reorderImports(false) importOrder("java", "javax", "org", "com", "net", "io") toggleOffOn() @@ -276,11 +276,11 @@ dependencies { implementation "org.openjfx:javafx-controls:21" implementation "org.openjfx:javafx-swing:21" } - - //security updates - implementation "org.springframework:spring-webmvc:6.2.0" - implementation("io.github.pixee:java-security-toolkit:1.2.0") + //security updates + implementation "org.springframework:spring-webmvc:6.2.1" + + implementation("io.github.pixee:java-security-toolkit:1.2.1") // implementation "org.yaml:snakeyaml:2.2" implementation 'com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4' @@ -301,7 +301,7 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion" implementation "org.springframework.session:spring-session-core:$springBootVersion" - + implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5' // Don't upgrade h2database runtimeOnly "com.h2database:h2:2.3.232" @@ -372,7 +372,7 @@ dependencies { implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion" implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion" implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion" - implementation "io.micrometer:micrometer-core:1.14.1" + implementation "io.micrometer:micrometer-core:1.14.2" implementation group: "com.google.zxing", name: "core", version: "3.5.3" // https://mvnrepository.com/artifact/org.commonmark/commonmark implementation "org.commonmark:commonmark:0.24.0" diff --git a/scripts/init.sh b/scripts/init.sh index b0e2a095..f839da2b 100644 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -16,10 +16,10 @@ fi # Check if TESSERACT_LANGS environment variable is set and is not empty if [[ -n "$TESSERACT_LANGS" ]]; then # Convert comma-separated values to a space-separated list - LANGS=$(echo $TESSERACT_LANGS | tr ',' ' ') + SPACE_SEPARATED_LANGS=$(echo $TESSERACT_LANGS | tr ',' ' ') pattern='^[a-zA-Z]{2,4}(_[a-zA-Z]{2,4})?$' # Install each language pack - for LANG in $LANGS; do + for LANG in $SPACE_SEPARATED_LANGS; do if [[ $LANG =~ $pattern ]]; then apk add --no-cache "tesseract-ocr-data-$LANG" else diff --git a/src/main/java/stirling/software/SPDF/LibreOfficeListener.java b/src/main/java/stirling/software/SPDF/LibreOfficeListener.java index 549a0092..7c78287d 100644 --- a/src/main/java/stirling/software/SPDF/LibreOfficeListener.java +++ b/src/main/java/stirling/software/SPDF/LibreOfficeListener.java @@ -6,9 +6,6 @@ import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import io.github.pixee.security.SystemCommand; import lombok.extern.slf4j.Slf4j; @@ -16,7 +13,6 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class LibreOfficeListener { - private static final Logger logger = LoggerFactory.getLogger(LibreOfficeListener.class); private static final long ACTIVITY_TIMEOUT = 20L * 60 * 1000; // 20 minutes private static final LibreOfficeListener INSTANCE = new LibreOfficeListener(); @@ -87,7 +83,7 @@ public class LibreOfficeListener { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - logger.error("exception", e); + log.error("exception", e); } // Check every 1 second } } diff --git a/src/main/java/stirling/software/SPDF/SPdfApplication.java b/src/main/java/stirling/software/SPDF/SPdfApplication.java index 1e66e1ce..e26fb111 100644 --- a/src/main/java/stirling/software/SPDF/SPdfApplication.java +++ b/src/main/java/stirling/software/SPDF/SPdfApplication.java @@ -13,8 +13,6 @@ import java.util.Properties; import javax.swing.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; @@ -36,8 +34,6 @@ import stirling.software.SPDF.model.ApplicationProperties; @Slf4j public class SPdfApplication { - private static final Logger logger = LoggerFactory.getLogger(SPdfApplication.class); - @Autowired private Environment env; @Autowired ApplicationProperties applicationProperties; @@ -96,7 +92,7 @@ public class SPdfApplication { if (Files.exists(Paths.get("configs/settings.yml"))) { propertyFiles.put("spring.config.additional-location", "file:configs/settings.yml"); } else { - logger.warn("External configuration file 'configs/settings.yml' does not exist."); + log.warn("External configuration file 'configs/settings.yml' does not exist."); } if (Files.exists(Paths.get("configs/custom_settings.yml"))) { @@ -109,7 +105,7 @@ public class SPdfApplication { "spring.config.additional-location", existingLocation + "file:configs/custom_settings.yml"); } else { - logger.warn("Custom configuration file 'configs/custom_settings.yml' does not exist."); + log.warn("Custom configuration file 'configs/custom_settings.yml' does not exist."); } Properties finalProps = new Properties(); @@ -132,16 +128,16 @@ public class SPdfApplication { Files.createDirectories(Path.of("customFiles/static/")); Files.createDirectories(Path.of("customFiles/templates/")); } catch (Exception e) { - logger.error("Error creating directories: {}", e.getMessage()); + log.error("Error creating directories: {}", e.getMessage()); } printStartupLogs(); } private static void printStartupLogs() { - logger.info("Stirling-PDF Started."); + log.info("Stirling-PDF Started."); String url = baseUrlStatic + ":" + getStaticPort(); - logger.info("Navigate to {}", url); + log.info("Navigate to {}", url); } @Autowired(required = false) @@ -170,11 +166,11 @@ public class SPdfApplication { SystemCommand.runCommand(rt, "xdg-open " + url); } } catch (Exception e) { - logger.error("Error opening browser: {}", e.getMessage()); + log.error("Error opening browser: {}", e.getMessage()); } } } - logger.info("Running configs {}", applicationProperties.toString()); + log.info("Running configs {}", applicationProperties.toString()); } @PreDestroy diff --git a/src/main/java/stirling/software/SPDF/config/AppConfig.java b/src/main/java/stirling/software/SPDF/config/AppConfig.java index e45a750b..6d8786e8 100644 --- a/src/main/java/stirling/software/SPDF/config/AppConfig.java +++ b/src/main/java/stirling/software/SPDF/config/AppConfig.java @@ -7,8 +7,6 @@ import java.nio.file.Paths; import java.util.Properties; import java.util.function.Predicate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -21,14 +19,14 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.thymeleaf.spring6.SpringTemplateEngine; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.ApplicationProperties; @Configuration @Lazy +@Slf4j public class AppConfig { - private static final Logger logger = LoggerFactory.getLogger(AppConfig.class); - @Autowired ApplicationProperties applicationProperties; @Bean @@ -61,7 +59,7 @@ public class AppConfig { props.load(resource.getInputStream()); return props.getProperty("version"); } catch (IOException e) { - logger.error("exception", e); + log.error("exception", e); } return "0.0.0"; } diff --git a/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java b/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java index c6853782..42dbf747 100644 --- a/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java +++ b/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java @@ -16,16 +16,15 @@ import org.simpleyaml.configuration.comments.CommentType; import org.simpleyaml.configuration.file.YamlFile; import org.simpleyaml.configuration.implementation.SimpleYamlImplementation; import org.simpleyaml.configuration.implementation.snakeyaml.lib.DumperOptions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; +import lombok.extern.slf4j.Slf4j; + +@Slf4j public class ConfigInitializer implements ApplicationContextInitializer { - private static final Logger logger = LoggerFactory.getLogger(ConfigInitializer.class); - @Override public void initialize(ConfigurableApplicationContext applicationContext) { try { @@ -149,7 +148,7 @@ public class ConfigInitializer .commentSide(settingsTemplateFile.getComment(path, CommentType.SIDE)); } else { // Log if the key is not found in both YAML files - logger.info("Key not found in both YAML files: " + path); + log.info("Key not found in both YAML files: " + path); } } } diff --git a/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java b/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java index c144007b..998d7525 100644 --- a/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java @@ -7,19 +7,19 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Service; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.ApplicationProperties; @Service +@Slf4j @DependsOn({"bookAndHtmlFormatsInstalled"}) public class EndpointConfiguration { - private static final Logger logger = LoggerFactory.getLogger(EndpointConfiguration.class); + private Map endpointStatuses = new ConcurrentHashMap<>(); private Map> endpointGroups = new ConcurrentHashMap<>(); @@ -43,7 +43,7 @@ public class EndpointConfiguration { public void disableEndpoint(String endpoint) { if (!endpointStatuses.containsKey(endpoint) || endpointStatuses.get(endpoint) != false) { - logger.debug("Disabling {}", endpoint); + log.debug("Disabling {}", endpoint); endpointStatuses.put(endpoint, false); } } @@ -87,7 +87,7 @@ public class EndpointConfiguration { .collect(Collectors.toList()); if (!disabledList.isEmpty()) { - logger.info( + log.info( "Total disabled endpoints: {}. Disabled endpoints: {}", disabledList.size(), String.join(", ", disabledList)); diff --git a/src/main/java/stirling/software/SPDF/config/interfaces/DatabaseBackupInterface.java b/src/main/java/stirling/software/SPDF/config/interfaces/DatabaseBackupInterface.java index 3ad11f2a..9d0e094a 100644 --- a/src/main/java/stirling/software/SPDF/config/interfaces/DatabaseBackupInterface.java +++ b/src/main/java/stirling/software/SPDF/config/interfaces/DatabaseBackupInterface.java @@ -6,6 +6,7 @@ import java.util.List; import stirling.software.SPDF.utils.FileInfo; public interface DatabaseBackupInterface { + void exportDatabase() throws IOException; boolean importDatabase(); diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2UserService.java b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2UserService.java index ebe734b5..5b2fb994 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2UserService.java +++ b/src/main/java/stirling/software/SPDF/config/security/oauth2/CustomOAuth2UserService.java @@ -2,8 +2,6 @@ package stirling.software.SPDF.config.security.oauth2; import java.util.Optional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.security.authentication.LockedException; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; @@ -13,6 +11,7 @@ import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.security.oauth2.core.oidc.user.OidcUser; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.config.security.LoginAttemptService; import stirling.software.SPDF.config.security.UserService; import stirling.software.SPDF.model.ApplicationProperties; @@ -20,6 +19,7 @@ import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2; import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client; import stirling.software.SPDF.model.User; +@Slf4j public class CustomOAuth2UserService implements OAuth2UserService { private final OidcUserService delegate = new OidcUserService(); @@ -30,8 +30,6 @@ public class CustomOAuth2UserService implements OAuth2UserService downloadFile(@PathVariable String fileName) { + description = "Downloads the specified database backup file from the server.") + @GetMapping("/download/{fileName}") + public ResponseEntity downloadFile( + @Parameter(description = "Name of the file to download", required = true) @PathVariable + String fileName) { if (fileName == null || fileName.isEmpty()) { throw new IllegalArgumentException("File must not be null or empty"); } @@ -141,4 +156,22 @@ public class DatabaseController { .build(); } } + + @Operation( + summary = "Create a database backup", + description = + "This endpoint triggers the creation of a database backup and redirects to the" + + " database management page.") + @GetMapping("/createDatabaseBackup") + public String createDatabaseBackup() { + try { + log.info("Starting database backup creation..."); + databaseBackupHelper.exportDatabase(); + log.info("Database backup successfully created."); + } catch (IOException e) { + log.error("Error creating database backup: {}", e.getMessage(), e); + return "redirect:/database?error=" + e.getMessage(); + } + return "redirect:/database?infoMessage=backupCreated"; + } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/MergeController.java b/src/main/java/stirling/software/SPDF/controller/api/MergeController.java index 9a60fcf6..b5d2cdc6 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/MergeController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/MergeController.java @@ -20,8 +20,6 @@ import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; import org.apache.pdfbox.pdmodel.interactive.form.PDField; import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -33,18 +31,18 @@ import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.general.MergePdfsRequest; import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.utils.GeneralUtils; import stirling.software.SPDF.utils.WebResponseUtils; @RestController +@Slf4j @RequestMapping("/api/v1/general") @Tag(name = "General", description = "General APIs") public class MergeController { - private static final Logger logger = LoggerFactory.getLogger(MergeController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -184,7 +182,7 @@ public class MergeController { baos.toByteArray(), mergedFileName); // Return the modified PDF } catch (Exception ex) { - logger.error("Error in merge pdf process", ex); + log.error("Error in merge pdf process", ex); throw ex; } finally { for (File file : filesToDelete) { diff --git a/src/main/java/stirling/software/SPDF/controller/api/MultiPageLayoutController.java b/src/main/java/stirling/software/SPDF/controller/api/MultiPageLayoutController.java index fbfec731..59b8bee3 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/MultiPageLayoutController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/MultiPageLayoutController.java @@ -12,8 +12,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject; import org.apache.pdfbox.util.Matrix; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -35,8 +33,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "General", description = "General APIs") public class MultiPageLayoutController { - private static final Logger logger = LoggerFactory.getLogger(MultiPageLayoutController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired diff --git a/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java b/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java index 8eb08dbf..77601b5d 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/RearrangePagesPDFController.java @@ -8,8 +8,6 @@ import java.util.List; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -22,6 +20,7 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.SortTypes; import stirling.software.SPDF.model.api.PDFWithPageNums; import stirling.software.SPDF.model.api.general.RearrangePagesRequest; @@ -31,11 +30,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/general") +@Slf4j @Tag(name = "General", description = "General APIs") public class RearrangePagesPDFController { - private static final Logger logger = LoggerFactory.getLogger(RearrangePagesPDFController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -202,7 +200,7 @@ public class RearrangePagesPDFController { throw new IllegalArgumentException("Unsupported custom mode"); } } catch (IllegalArgumentException e) { - logger.error("Unsupported custom mode", e); + log.error("Unsupported custom mode", e); return null; } } @@ -230,8 +228,8 @@ public class RearrangePagesPDFController { } else { newPageOrder = GeneralUtils.parsePageList(pageOrderArr, totalPages, false); } - logger.info("newPageOrder = " + newPageOrder); - logger.info("totalPages = " + totalPages); + log.info("newPageOrder = " + newPageOrder); + log.info("totalPages = " + totalPages); // Create a new list to hold the pages in the new order List newPages = new ArrayList<>(); for (int i = 0; i < newPageOrder.size(); i++) { @@ -254,7 +252,7 @@ public class RearrangePagesPDFController { .replaceFirst("[.][^.]+$", "") + "_rearranged.pdf"); } catch (IOException e) { - logger.error("Failed rearranging documents", e); + log.error("Failed rearranging documents", e); return null; } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/RotationController.java b/src/main/java/stirling/software/SPDF/controller/api/RotationController.java index 1c416a07..9ffc61b6 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/RotationController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/RotationController.java @@ -5,8 +5,6 @@ import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageTree; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -28,8 +26,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "General", description = "General APIs") public class RotationController { - private static final Logger logger = LoggerFactory.getLogger(RotationController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired diff --git a/src/main/java/stirling/software/SPDF/controller/api/ScalePagesController.java b/src/main/java/stirling/software/SPDF/controller/api/ScalePagesController.java index 19e13502..c098a005 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/ScalePagesController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/ScalePagesController.java @@ -13,8 +13,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject; import org.apache.pdfbox.util.Matrix; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -36,8 +34,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "General", description = "General APIs") public class ScalePagesController { - private static final Logger logger = LoggerFactory.getLogger(ScalePagesController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired diff --git a/src/main/java/stirling/software/SPDF/controller/api/SplitPDFController.java b/src/main/java/stirling/software/SPDF/controller/api/SplitPDFController.java index a8e74e2a..ef6dc9a3 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/SplitPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/SplitPDFController.java @@ -13,8 +13,6 @@ import java.util.zip.ZipOutputStream; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -28,16 +26,17 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.PDFWithPageNums; import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/general") +@Slf4j @Tag(name = "General", description = "General APIs") public class SplitPDFController { - private static final Logger logger = LoggerFactory.getLogger(SplitPDFController.class); private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -73,7 +72,7 @@ public class SplitPDFController { pageNumbers.add(totalPages - 1); } - logger.info( + log.info( "Splitting PDF into pages: {}", pageNumbers.stream().map(String::valueOf).collect(Collectors.joining(","))); @@ -86,7 +85,7 @@ public class SplitPDFController { for (int i = previousPageNumber; i <= splitPoint; i++) { PDPage page = document.getPage(i); splitDocument.addPage(page); - logger.info("Adding page {} to split document", i); + log.info("Adding page {} to split document", i); } previousPageNumber = splitPoint + 1; @@ -98,7 +97,7 @@ public class SplitPDFController { splitDocumentsBoas.add(baos); } catch (Exception e) { - logger.error("Failed splitting documents and saving them", e); + log.error("Failed splitting documents and saving them", e); throw e; } } @@ -124,15 +123,14 @@ public class SplitPDFController { zipOut.write(pdf); zipOut.closeEntry(); - logger.info("Wrote split document {} to zip file", fileName); + log.info("Wrote split document {} to zip file", fileName); } } catch (Exception e) { - logger.error("Failed writing to zip", e); + log.error("Failed writing to zip", e); throw e; } - logger.info( - "Successfully created zip file with split documents: {}", zipFile.toString()); + log.info("Successfully created zip file with split documents: {}", zipFile.toString()); byte[] data = Files.readAllBytes(zipFile); Files.deleteIfExists(zipFile); @@ -159,7 +157,7 @@ public class SplitPDFController { Files.deleteIfExists(zipFile); } } catch (Exception e) { - logger.error("Error while cleaning up resources", e); + log.error("Error while cleaning up resources", e); } } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/SplitPdfByChaptersController.java b/src/main/java/stirling/software/SPDF/controller/api/SplitPdfByChaptersController.java index c74ed294..37b4a4c2 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/SplitPdfByChaptersController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/SplitPdfByChaptersController.java @@ -13,8 +13,6 @@ import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -32,6 +30,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.PdfMetadata; import stirling.software.SPDF.model.api.SplitPdfByChaptersRequest; import stirling.software.SPDF.service.PdfMetadataService; @@ -39,12 +38,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/general") +@Slf4j @Tag(name = "General", description = "General APIs") public class SplitPdfByChaptersController { - private static final Logger logger = - LoggerFactory.getLogger(SplitPdfByChaptersController.class); - private final PdfMetadataService pdfMetadataService; @Autowired @@ -74,7 +71,7 @@ public class SplitPdfByChaptersController { PDDocumentOutline outline = sourceDocument.getDocumentCatalog().getDocumentOutline(); if (outline == null) { - logger.warn("No outline found for {}", file.getOriginalFilename()); + log.warn("No outline found for {}", file.getOriginalFilename()); return ResponseEntity.badRequest().body("No outline found".getBytes()); } List bookmarks = new ArrayList<>(); @@ -92,7 +89,7 @@ public class SplitPdfByChaptersController { Bookmark lastBookmark = bookmarks.get(bookmarks.size() - 1); } catch (Exception e) { - logger.error("Unable to extract outline items", e); + log.error("Unable to extract outline items", e); return ResponseEntity.internalServerError() .body("Unable to extract outline items".getBytes()); } @@ -107,7 +104,7 @@ public class SplitPdfByChaptersController { bookmarks = mergeBookmarksThatCorrespondToSamePage(bookmarks); } for (Bookmark bookmark : bookmarks) { - logger.info( + log.info( "{}::::{} to {}", bookmark.getTitle(), bookmark.getStartPage(), @@ -136,7 +133,7 @@ public class SplitPdfByChaptersController { Files.deleteIfExists(zipFile); } } catch (Exception e) { - logger.error("Error while cleaning up resources", e); + log.error("Error while cleaning up resources", e); } } } @@ -256,14 +253,14 @@ public class SplitPdfByChaptersController { zipOut.write(pdf); zipOut.closeEntry(); - logger.info("Wrote split document {} to zip file", fileName); + log.info("Wrote split document {} to zip file", fileName); } } catch (Exception e) { - logger.error("Failed writing to zip", e); + log.error("Failed writing to zip", e); throw e; } - logger.info("Successfully created zip file with split documents: {}", zipFile); + log.info("Successfully created zip file with split documents: {}", zipFile); return zipFile; } @@ -284,7 +281,7 @@ public class SplitPdfByChaptersController { i++) { PDPage page = sourceDocument.getPage(i); splitDocument.addPage(page); - logger.info("Adding page {} to split document", i); + log.info("Adding page {} to split document", i); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (includeMetadata) { @@ -295,7 +292,7 @@ public class SplitPdfByChaptersController { splitDocumentsBoas.add(baos); } catch (Exception e) { - logger.error("Failed splitting documents and saving them", e); + log.error("Failed splitting documents and saving them", e); throw e; } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java b/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java index eaa9c86d..29040a60 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySectionsController.java @@ -18,8 +18,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject; import org.apache.pdfbox.util.Matrix; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -42,9 +40,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "General", description = "General APIs") public class SplitPdfBySectionsController { - private static final Logger logger = - LoggerFactory.getLogger(SplitPdfBySectionsController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired diff --git a/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySizeController.java b/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySizeController.java index 6016e532..97e42dca 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySizeController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/SplitPdfBySizeController.java @@ -10,8 +10,6 @@ import java.util.zip.ZipOutputStream; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -25,6 +23,7 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.general.SplitPdfBySizeOrCountRequest; import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.utils.GeneralUtils; @@ -32,10 +31,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/general") +@Slf4j @Tag(name = "General", description = "General APIs") public class SplitPdfBySizeController { - private static final Logger logger = LoggerFactory.getLogger(SplitPdfBySizeController.class); private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -78,7 +77,7 @@ public class SplitPdfBySizeController { } } catch (Exception e) { - logger.error("exception", e); + log.error("exception", e); } finally { data = Files.readAllBytes(zipFile); Files.deleteIfExists(zipFile); diff --git a/src/main/java/stirling/software/SPDF/controller/api/ToSinglePageController.java b/src/main/java/stirling/software/SPDF/controller/api/ToSinglePageController.java index 9401f3a6..07b2f4d4 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/ToSinglePageController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/ToSinglePageController.java @@ -11,8 +11,6 @@ import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -32,8 +30,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "General", description = "General APIs") public class ToSinglePageController { - private static final Logger logger = LoggerFactory.getLogger(ToSinglePageController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired diff --git a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java index b5eec392..06f964f4 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertImgPDFController.java @@ -14,8 +14,6 @@ import java.util.zip.ZipOutputStream; import org.apache.commons.io.FileUtils; import org.apache.pdfbox.rendering.ImageType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -29,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.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.converters.ConvertToImageRequest; import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest; import stirling.software.SPDF.service.CustomPDDocumentFactory; @@ -40,11 +39,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/convert") +@Slf4j @Tag(name = "Convert", description = "Convert APIs") public class ConvertImgPDFController { - private static final Logger logger = LoggerFactory.getLogger(ConvertImgPDFController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -95,7 +93,7 @@ public class ConvertImgPDFController { Integer.valueOf(dpi), filename); if (result == null || result.length == 0) { - logger.error("resultant bytes for {} is null, error converting ", filename); + log.error("resultant bytes for {} is null, error converting ", filename); } if ("webp".equalsIgnoreCase(imageFormat) && !CheckProgramInstall.isPythonAvailable()) { throw new IOException("Python is not installed. Required for WebP conversion."); @@ -142,7 +140,7 @@ public class ConvertImgPDFController { .collect(Collectors.toList()); if (webpFiles.isEmpty()) { - logger.error("No WebP files were created in: {}", tempOutputDir.toString()); + log.error("No WebP files were created in: {}", tempOutputDir.toString()); throw new IOException( "No WebP files were created. " + resultProcess.getMessages()); } @@ -194,7 +192,7 @@ public class ConvertImgPDFController { FileUtils.deleteDirectory(tempOutputDir.toFile()); } } catch (Exception e) { - logger.error("Error cleaning up temporary files", e); + log.error("Error cleaning up temporary files", e); } } } @@ -210,7 +208,13 @@ public class ConvertImgPDFController { String fitOption = request.getFitOption(); String colorType = request.getColorType(); boolean autoRotate = request.isAutoRotate(); - + // Handle Null entries for formdata + if (colorType == null || colorType.isBlank()) { + colorType = "color"; + } + if (fitOption == null || fitOption.isEmpty()) { + fitOption = "fillPage"; + } // Convert the file to PDF and get the resulting bytes byte[] bytes = PdfUtils.imageToPdf(file, fitOption, autoRotate, colorType, pdfDocumentFactory); diff --git a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToPDFA.java b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToPDFA.java index c72ddf0f..5caee0f9 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToPDFA.java +++ b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertPDFToPDFA.java @@ -8,8 +8,6 @@ import java.util.Arrays; import java.util.List; import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -22,6 +20,7 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.converters.PdfToPdfARequest; import stirling.software.SPDF.utils.ProcessExecutor; import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult; @@ -29,11 +28,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/convert") +@Slf4j @Tag(name = "Convert", description = "Convert APIs") public class ConvertPDFToPDFA { - private static final Logger logger = LoggerFactory.getLogger(ConvertPDFToPDFA.class); - @PostMapping(consumes = "multipart/form-data", value = "/pdf/pdfa") @Operation( summary = "Convert a PDF to a PDF/A", @@ -46,7 +44,7 @@ public class ConvertPDFToPDFA { // Validate input file type if (!"application/pdf".equals(inputFile.getContentType())) { - logger.error("Invalid input file type: {}", inputFile.getContentType()); + log.error("Invalid input file type: {}", inputFile.getContentType()); throw new IllegalArgumentException("Input file must be a PDF"); } @@ -96,7 +94,7 @@ public class ConvertPDFToPDFA { .runCommandWithOutputHandling(command); if (returnCode.getRc() != 0) { - logger.error("PDF/A conversion failed with return code: {}", returnCode.getRc()); + log.error("PDF/A conversion failed with return code: {}", returnCode.getRc()); throw new RuntimeException("PDF/A conversion failed"); } diff --git a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPDF.java b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPDF.java index 6119bfcf..d6ae1a47 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPDF.java +++ b/src/main/java/stirling/software/SPDF/controller/api/converters/ConvertWebsiteToPDF.java @@ -7,8 +7,6 @@ import java.util.ArrayList; import java.util.List; import org.apache.pdfbox.pdmodel.PDDocument; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -19,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.converters.UrlToPdfRequest; import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.utils.GeneralUtils; @@ -28,11 +27,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @Tag(name = "Convert", description = "Convert APIs") +@Slf4j @RequestMapping("/api/v1/convert") public class ConvertWebsiteToPDF { - private static final Logger logger = LoggerFactory.getLogger(ConvertWebsiteToPDF.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -88,7 +86,7 @@ public class ConvertWebsiteToPDF { try { Files.deleteIfExists(tempOutputFile); } catch (IOException e) { - logger.error("Error deleting temporary output file", e); + log.error("Error deleting temporary output file", e); } } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/converters/ExtractCSVController.java b/src/main/java/stirling/software/SPDF/controller/api/converters/ExtractCSVController.java index f86b7aa3..f0a4c267 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/converters/ExtractCSVController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/converters/ExtractCSVController.java @@ -7,8 +7,6 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.QuoteMode; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.ContentDisposition; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -34,8 +32,6 @@ import technology.tabula.writers.Writer; @Tag(name = "Convert", description = "Convert APIs") public class ExtractCSVController { - private static final Logger logger = LoggerFactory.getLogger(ExtractCSVController.class); - @PostMapping(value = "/pdf/csv", consumes = "multipart/form-data") @Operation( summary = "Extracts a CSV document from a PDF", diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/AutoRenameController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/AutoRenameController.java index 8bacad6d..8f8b13f0 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/AutoRenameController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/AutoRenameController.java @@ -9,8 +9,6 @@ import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; import org.apache.pdfbox.text.TextPosition; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; @@ -22,16 +20,16 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.misc.ExtractHeaderRequest; import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/misc") +@Slf4j @Tag(name = "Misc", description = "Miscellaneous APIs") public class AutoRenameController { - private static final Logger logger = LoggerFactory.getLogger(AutoRenameController.class); - private static final float TITLE_FONT_SIZE_THRESHOLD = 20.0f; private static final int LINE_LIMIT = 200; @@ -133,7 +131,7 @@ public class AutoRenameController { header = header.replaceAll("[/\\\\?%*:|\"<>]", "").trim(); return WebResponseUtils.pdfDocToWebResponse(document, header + ".pdf"); } else { - logger.info("File has no good title to be found"); + log.info("File has no good title to be found"); return WebResponseUtils.pdfDocToWebResponse( document, Filenames.toSimpleFileName(file.getOriginalFilename())); } diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java index 88d113ec..23c9ac28 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/AutoSplitPdfController.java @@ -14,8 +14,6 @@ import java.util.zip.ZipOutputStream; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.PDFRenderer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -37,16 +35,17 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest; import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/misc") +@Slf4j @Tag(name = "Misc", description = "Miscellaneous APIs") public class AutoSplitPdfController { - private static final Logger logger = LoggerFactory.getLogger(AutoSplitPdfController.class); private static final String QR_CONTENT = "https://github.com/Stirling-Tools/Stirling-PDF"; private static final String QR_CONTENT_OLD = "https://github.com/Frooodle/Stirling-PDF"; @@ -134,7 +133,7 @@ public class AutoSplitPdfController { try { document.close(); } catch (IOException e) { - logger.error("Error closing main PDDocument", e); + log.error("Error closing main PDDocument", e); } } @@ -142,7 +141,7 @@ public class AutoSplitPdfController { try { splitDoc.close(); } catch (IOException e) { - logger.error("Error closing split PDDocument", e); + log.error("Error closing split PDDocument", e); } } @@ -150,7 +149,7 @@ public class AutoSplitPdfController { try { Files.deleteIfExists(zipFile); } catch (IOException e) { - logger.error("Error deleting temporary zip file", e); + log.error("Error deleting temporary zip file", e); } } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/BlankPageController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/BlankPageController.java index bf046d65..f88432dd 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/BlankPageController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/BlankPageController.java @@ -14,8 +14,6 @@ import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageTree; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.text.PDFTextStripper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -30,6 +28,7 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.misc.RemoveBlankPagesRequest; import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.utils.PdfUtils; @@ -37,11 +36,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/misc") +@Slf4j @Tag(name = "Misc", description = "Miscellaneous APIs") public class BlankPageController { - private static final Logger logger = LoggerFactory.getLogger(BlankPageController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -71,7 +69,7 @@ public class BlankPageController { PDFRenderer pdfRenderer = new PDFRenderer(document); pdfRenderer.setSubsamplingAllowed(true); for (PDPage page : pages) { - logger.info("checking page {}", pageIndex); + log.info("checking page {}", pageIndex); textStripper.setStartPage(pageIndex + 1); textStripper.setEndPage(pageIndex + 1); String pageText = textStripper.getText(document); @@ -79,12 +77,12 @@ public class BlankPageController { boolean blank = true; if (hasText) { - logger.info("page {} has text, not blank", pageIndex); + log.info("page {} has text, not blank", pageIndex); blank = false; } else { boolean hasImages = PdfUtils.hasImagesOnPage(page); if (hasImages) { - logger.info("page {} has image, running blank detection", pageIndex); + log.info("page {} has image, running blank detection", pageIndex); // Render image and save as temp file BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 30); blank = isBlankImage(image, threshold, whitePercent, threshold); @@ -92,10 +90,10 @@ public class BlankPageController { } if (blank) { - logger.info("Skipping, Image was blank for page #{}", pageIndex); + log.info("Skipping, Image was blank for page #{}", pageIndex); blankPages.add(page); } else { - logger.info("page {} has image which is not blank", pageIndex); + log.info("page {} has image which is not blank", pageIndex); nonBlankPages.add(page); } @@ -121,12 +119,12 @@ public class BlankPageController { zos.close(); - logger.info("Returning ZIP file: {}", filename + "_processed.zip"); + log.info("Returning ZIP file: {}", filename + "_processed.zip"); return WebResponseUtils.boasToWebResponse( baos, filename + "_processed.zip", MediaType.APPLICATION_OCTET_STREAM); } catch (IOException e) { - logger.error("exception", e); + log.error("exception", e); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } @@ -149,7 +147,7 @@ public class BlankPageController { public static boolean isBlankImage( BufferedImage image, int threshold, double whitePercent, int blurSize) { if (image == null) { - logger.info("Error: Image is null"); + log.info("Error: Image is null"); return false; } @@ -167,7 +165,7 @@ public class BlankPageController { } double whitePixelPercentage = (whitePixels / (double) totalPixels) * 100; - logger.info(String.format("Page has white pixel percent of %.2f%%", whitePixelPercentage)); + log.info(String.format("Page has white pixel percent of %.2f%%", whitePixelPercentage)); return whitePixelPercentage >= whitePercent; } diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java index 723bd371..39bf37b0 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java @@ -17,8 +17,6 @@ import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDResources; import org.apache.pdfbox.pdmodel.graphics.PDXObject; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -31,6 +29,7 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.misc.OptimizePdfRequest; import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.utils.GeneralUtils; @@ -40,11 +39,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/misc") +@Slf4j @Tag(name = "Misc", description = "Miscellaneous APIs") public class CompressController { - private static final Logger logger = LoggerFactory.getLogger(CompressController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -191,7 +189,7 @@ public class CompressController { incrementOptimizeLevel( optimizeLevel, outputFileSize, expectedOutputSize); if (autoMode && optimizeLevel > 9) { - logger.info("Maximum compression level reached in auto mode"); + log.info("Maximum compression level reached in auto mode"); sizeMet = true; } } @@ -203,7 +201,7 @@ public class CompressController { // Check if optimized file is larger than the original if (pdfBytes.length > inputFileSize) { - logger.warn( + log.warn( "Optimized file is larger than the original. Returning the original file instead."); finalFile = tempInputFile; } @@ -234,7 +232,7 @@ public class CompressController { private int incrementOptimizeLevel(int currentLevel, long currentSize, long targetSize) { double currentRatio = currentSize / (double) targetSize; - logger.info("Current compression ratio: {}", String.format("%.2f", currentRatio)); + log.info("Current compression ratio: {}", String.format("%.2f", currentRatio)); if (currentRatio > 2.0) { return Math.min(9, currentLevel + 3); diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImageScansController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImageScansController.java index 966eec84..2b83e618 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImageScansController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImageScansController.java @@ -17,8 +17,6 @@ import org.apache.commons.io.FileUtils; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.PDFRenderer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; @@ -31,6 +29,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.misc.ExtractImageScansRequest; import stirling.software.SPDF.utils.CheckProgramInstall; import stirling.software.SPDF.utils.ProcessExecutor; @@ -39,11 +38,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/misc") +@Slf4j @Tag(name = "Misc", description = "Miscellaneous APIs") public class ExtractImageScansController { - private static final Logger logger = LoggerFactory.getLogger(ExtractImageScansController.class); - @PostMapping(consumes = "multipart/form-data", value = "/extract-image-scans") @Operation( summary = "Extract image scans from an input file", @@ -201,7 +199,7 @@ public class ExtractImageScansController { try { Files.deleteIfExists(path); } catch (IOException e) { - logger.error("Failed to delete temporary image file: " + path, e); + log.error("Failed to delete temporary image file: " + path, e); } }); @@ -209,7 +207,7 @@ public class ExtractImageScansController { try { Files.deleteIfExists(tempZipFile); } catch (IOException e) { - logger.error("Failed to delete temporary zip file: " + tempZipFile, e); + log.error("Failed to delete temporary zip file: " + tempZipFile, e); } } @@ -218,7 +216,7 @@ public class ExtractImageScansController { try { FileUtils.deleteDirectory(dir.toFile()); } catch (IOException e) { - logger.error("Failed to delete temporary directory: " + dir, e); + log.error("Failed to delete temporary directory: " + dir, e); } }); } diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImagesController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImagesController.java index 075de0d1..5dfeedb7 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImagesController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/ExtractImagesController.java @@ -25,8 +25,6 @@ import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -39,17 +37,17 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.PDFExtractImagesRequest; import stirling.software.SPDF.utils.ImageProcessingUtils; import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/misc") +@Slf4j @Tag(name = "Misc", description = "Miscellaneous APIs") public class ExtractImagesController { - private static final Logger logger = LoggerFactory.getLogger(ExtractImagesController.class); - @PostMapping(consumes = "multipart/form-data", value = "/extract-images") @Operation( summary = "Extract images from a PDF file", @@ -107,7 +105,7 @@ public class ExtractImagesController { allowDuplicates); } catch (IOException e) { // Log the error and continue processing other pages - logger.error( + log.error( "Error extracting images from page {}: {}", pageNum, e.getMessage()); @@ -167,7 +165,7 @@ public class ExtractImagesController { try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { - logger.error("MD5 algorithm not available for extractImages hash.", e); + log.error("MD5 algorithm not available for extractImages hash.", e); return; } if (page.getResources() == null || page.getResources().getXObjectNames() == null) { diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/FakeScanControllerWIP.java b/src/main/java/stirling/software/SPDF/controller/api/misc/FakeScanControllerWIP.java index 7206d1cd..f8e026a8 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/FakeScanControllerWIP.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/FakeScanControllerWIP.java @@ -27,8 +27,6 @@ import org.apache.pdfbox.pdmodel.graphics.image.JPEGFactory; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; @@ -50,8 +48,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "Misc", description = "Miscellaneous APIs") public class FakeScanControllerWIP { - private static final Logger logger = LoggerFactory.getLogger(FakeScanControllerWIP.class); - // TODO finish @PostMapping(consumes = "multipart/form-data", value = "/fake-scan") @Hidden diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/FlattenController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/FlattenController.java index c99b5f73..10acbeea 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/FlattenController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/FlattenController.java @@ -12,8 +12,6 @@ import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -26,17 +24,17 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.misc.FlattenRequest; import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/misc") +@Slf4j @Tag(name = "Misc", description = "Miscellaneous APIs") public class FlattenController { - private static final Logger logger = LoggerFactory.getLogger(FlattenController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -84,7 +82,7 @@ public class FlattenController { contentStream.drawImage(pdImage, 0, 0, pageWidth, pageHeight); } } catch (IOException e) { - logger.error("exception", e); + log.error("exception", e); } } return WebResponseUtils.pdfDocToWebResponse( diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java index 274bea10..a26c4839 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/MetadataController.java @@ -11,8 +11,6 @@ import org.apache.pdfbox.Loader; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentInformation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; @@ -26,17 +24,17 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.misc.MetadataRequest; import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.propertyeditor.StringToMapPropertyEditor; @RestController @RequestMapping("/api/v1/misc") +@Slf4j @Tag(name = "Misc", description = "Miscellaneous APIs") public class MetadataController { - private static final Logger logger = LoggerFactory.getLogger(MetadataController.class); - private String checkUndefined(String entry) { // Check if the string is "undefined" if ("undefined".equals(entry)) { @@ -148,7 +146,7 @@ public class MetadataController { creationDateCal.setTime( new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(creationDate)); } catch (ParseException e) { - logger.error("exception", e); + log.error("exception", e); } info.setCreationDate(creationDateCal); } else { @@ -160,7 +158,7 @@ public class MetadataController { modificationDateCal.setTime( new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(modificationDate)); } catch (ParseException e) { - logger.error("exception", e); + log.error("exception", e); } info.setModificationDate(modificationDateCal); } else { diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/OverlayImageController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/OverlayImageController.java index 893fc1e5..951515ad 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/OverlayImageController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/OverlayImageController.java @@ -2,8 +2,6 @@ package stirling.software.SPDF.controller.api.misc; import java.io.IOException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -17,6 +15,7 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.misc.OverlayImageRequest; import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.utils.PdfUtils; @@ -24,11 +23,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/misc") +@Slf4j @Tag(name = "Misc", description = "Miscellaneous APIs") public class OverlayImageController { - private static final Logger logger = LoggerFactory.getLogger(OverlayImageController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -60,7 +58,7 @@ public class OverlayImageController { .replaceFirst("[.][^.]+$", "") + "_overlayed.pdf"); } catch (IOException e) { - logger.error("Failed to add image to PDF", e); + log.error("Failed to add image to PDF", e); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java index e42998d1..040d5e96 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/PageNumbersController.java @@ -10,8 +10,6 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.font.Standard14Fonts; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -35,8 +33,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "Misc", description = "Miscellaneous APIs") public class PageNumbersController { - private static final Logger logger = LoggerFactory.getLogger(PageNumbersController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/RepairController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/RepairController.java index b59bd5b4..374d0c53 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/RepairController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/RepairController.java @@ -6,8 +6,6 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -31,8 +29,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "Misc", description = "Miscellaneous APIs") public class RepairController { - private static final Logger logger = LoggerFactory.getLogger(RepairController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/ShowJavascript.java b/src/main/java/stirling/software/SPDF/controller/api/misc/ShowJavascript.java index a608fde9..d252800e 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/ShowJavascript.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/ShowJavascript.java @@ -7,8 +7,6 @@ import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.common.PDNameTreeNode; import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -29,8 +27,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "Misc", description = "Miscellaneous APIs") public class ShowJavascript { - private static final Logger logger = LoggerFactory.getLogger(ShowJavascript.class); - @PostMapping(consumes = "multipart/form-data", value = "/show-javascript") @Operation( summary = "Grabs all JS from a PDF and returns a single JS file with all code", diff --git a/src/main/java/stirling/software/SPDF/controller/api/pipeline/ApiDocService.java b/src/main/java/stirling/software/SPDF/controller/api/pipeline/ApiDocService.java index 771d7b45..2c5b9fac 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/pipeline/ApiDocService.java +++ b/src/main/java/stirling/software/SPDF/controller/api/pipeline/ApiDocService.java @@ -7,8 +7,6 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -21,17 +19,17 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.ServletContext; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.SPdfApplication; import stirling.software.SPDF.model.ApiEndpoint; import stirling.software.SPDF.model.Role; @Service +@Slf4j public class ApiDocService { private final Map apiDocumentation = new HashMap<>(); - private static final Logger logger = LoggerFactory.getLogger(ApiDocService.class); - @Autowired private ServletContext servletContext; private String getApiDocsUrl() { @@ -135,7 +133,7 @@ public class ApiDocService { }); } catch (Exception e) { // Handle exceptions - logger.error("Error grabbing swagger doc, body result {}", apiDocsJson); + log.error("Error grabbing swagger doc, body result {}", apiDocsJson); } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java index dfa45096..890ae723 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineController.java @@ -8,8 +8,6 @@ import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; @@ -26,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.PipelineConfig; import stirling.software.SPDF.model.api.HandleDataRequest; @@ -33,11 +32,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/pipeline") +@Slf4j @Tag(name = "Pipeline", description = "Pipeline APIs") public class PipelineController { - private static final Logger logger = LoggerFactory.getLogger(PipelineController.class); - final String watchedFoldersDir = "./pipeline/watchedFolders/"; final String finishedFoldersDir = "./pipeline/finishedFolders/"; @Autowired PipelineProcessor processor; @@ -56,7 +54,7 @@ public class PipelineController { return null; } PipelineConfig config = objectMapper.readValue(jsonString, PipelineConfig.class); - logger.info("Received POST request to /handleData with {} files", files.length); + log.info("Received POST request to /handleData with {} files", files.length); try { List inputFiles = processor.generateInputFiles(files); if (inputFiles == null || inputFiles.size() == 0) { @@ -71,7 +69,7 @@ public class PipelineController { is.read(bytes); is.close(); - logger.info("Returning single file response..."); + log.info("Returning single file response..."); return WebResponseUtils.bytesToWebResponse( bytes, singleFile.getFilename(), MediaType.APPLICATION_OCTET_STREAM); } else if (outputFiles == null) { @@ -118,11 +116,11 @@ public class PipelineController { zipOut.close(); - logger.info("Returning zipped file response..."); + log.info("Returning zipped file response..."); return WebResponseUtils.boasToWebResponse( baos, "output.zip", MediaType.APPLICATION_OCTET_STREAM); } catch (Exception e) { - logger.error("Error handling data: ", e); + log.error("Error handling data: ", e); return null; } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineDirectoryProcessor.java b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineDirectoryProcessor.java index 25531880..a46ea8ae 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineDirectoryProcessor.java +++ b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineDirectoryProcessor.java @@ -16,8 +16,6 @@ import java.util.List; import java.util.Optional; import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.io.ByteArrayResource; @@ -27,14 +25,15 @@ import org.springframework.stereotype.Service; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.PipelineConfig; import stirling.software.SPDF.model.PipelineOperation; import stirling.software.SPDF.utils.FileMonitor; @Service +@Slf4j public class PipelineDirectoryProcessor { - private static final Logger logger = LoggerFactory.getLogger(PipelineDirectoryProcessor.class); @Autowired private ObjectMapper objectMapper; @Autowired private ApiDocService apiDocService; @Autowired PipelineProcessor processor; @@ -56,9 +55,9 @@ public class PipelineDirectoryProcessor { if (!Files.exists(watchedFolderPath)) { try { Files.createDirectories(watchedFolderPath); - logger.info("Created directory: {}", watchedFolderPath); + log.info("Created directory: {}", watchedFolderPath); } catch (IOException e) { - logger.error("Error creating directory: {}", watchedFolderPath, e); + log.error("Error creating directory: {}", watchedFolderPath, e); return; } } @@ -71,21 +70,21 @@ public class PipelineDirectoryProcessor { handleDirectory(t); } } catch (Exception e) { - logger.error("Error handling directory: {}", t, e); + log.error("Error handling directory: {}", t, e); } }); } catch (Exception e) { - logger.error("Error walking through directory: {}", watchedFolderPath, e); + log.error("Error walking through directory: {}", watchedFolderPath, e); } } public void handleDirectory(Path dir) throws IOException { - logger.info("Handling directory: {}", dir); + log.info("Handling directory: {}", dir); Path processingDir = createProcessingDirectory(dir); Optional jsonFileOptional = findJsonFile(dir); if (!jsonFileOptional.isPresent()) { - logger.warn("No .JSON settings file found. No processing will happen for dir {}.", dir); + log.warn("No .JSON settings file found. No processing will happen for dir {}.", dir); return; } @@ -98,7 +97,7 @@ public class PipelineDirectoryProcessor { Path processingDir = dir.resolve("processing"); if (!Files.exists(processingDir)) { Files.createDirectory(processingDir); - logger.info("Created processing directory: {}", processingDir); + log.info("Created processing directory: {}", processingDir); } return processingDir; } @@ -111,7 +110,7 @@ public class PipelineDirectoryProcessor { private PipelineConfig readAndParseJson(Path jsonFile) throws IOException { String jsonString = new String(Files.readAllBytes(jsonFile), StandardCharsets.UTF_8); - logger.debug("Reading JSON file: {}", jsonFile); + log.debug("Reading JSON file: {}", jsonFile); return objectMapper.readValue(jsonString, PipelineConfig.class); } @@ -121,7 +120,7 @@ public class PipelineDirectoryProcessor { validateOperation(operation); File[] files = collectFilesForProcessing(dir, jsonFile, operation); if (files == null || files.length == 0) { - logger.debug("No files detected for {} ", dir); + log.debug("No files detected for {} ", dir); return; } List filesToProcess = prepareFilesForProcessing(files, processingDir); @@ -202,7 +201,7 @@ public class PipelineDirectoryProcessor { moveAndRenameFiles(outputFiles, config, dir); deleteOriginalFiles(filesToProcess, processingDir); } catch (Exception e) { - logger.error("error during processing", e); + log.error("error during processing", e); moveFilesBack(filesToProcess, processingDir); } } @@ -215,7 +214,7 @@ public class PipelineDirectoryProcessor { if (!Files.exists(outputPath)) { Files.createDirectories(outputPath); - logger.info("Created directory: {}", outputPath); + log.info("Created directory: {}", outputPath); } Path outputFile = outputPath.resolve(outputFileName); @@ -223,7 +222,7 @@ public class PipelineDirectoryProcessor { os.write(((ByteArrayResource) resource).getByteArray()); } - logger.info("File moved and renamed to {}", outputFile); + log.info("File moved and renamed to {}", outputFile); } } @@ -264,7 +263,7 @@ public class PipelineDirectoryProcessor { throws IOException { for (File file : filesToProcess) { Files.deleteIfExists(processingDir.resolve(file.getName())); - logger.info("Deleted original file: {}", file.getName()); + log.info("Deleted original file: {}", file.getName()); } } @@ -272,12 +271,12 @@ public class PipelineDirectoryProcessor { for (File file : filesToProcess) { try { Files.move(processingDir.resolve(file.getName()), file.toPath()); - logger.info( + log.info( "Moved file back to original location: {} , {}", file.toPath(), file.getName()); } catch (IOException e) { - logger.error("Error moving file back to original location: {}", file.getName(), e); + log.error("Error moving file back to original location: {}", file.getName(), e); } } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java index 00496036..cfa6fbec 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java +++ b/src/main/java/stirling/software/SPDF/controller/api/pipeline/PipelineProcessor.java @@ -19,8 +19,6 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.Resource; @@ -40,16 +38,16 @@ import io.github.pixee.security.Filenames; import io.github.pixee.security.ZipSecurity; import jakarta.servlet.ServletContext; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.SPdfApplication; import stirling.software.SPDF.model.PipelineConfig; import stirling.software.SPDF.model.PipelineOperation; import stirling.software.SPDF.model.Role; @Service +@Slf4j public class PipelineProcessor { - private static final Logger logger = LoggerFactory.getLogger(PipelineProcessor.class); - @Autowired private ApiDocService apiDocService; @Autowired(required = false) @@ -81,7 +79,7 @@ public class PipelineProcessor { String operation = pipelineOperation.getOperation(); boolean isMultiInputOperation = apiDocService.isMultiInput(operation); - logger.info( + log.info( "Running operation: {} isMultiInputOperation {}", operation, isMultiInputOperation); @@ -124,7 +122,7 @@ public class PipelineProcessor { if (operation.startsWith("filter-") && (response.getBody() == null || response.getBody().length == 0)) { - logger.info("Skipping file due to failing {}", operation); + log.info("Skipping file due to failing {}", operation); continue; } @@ -208,7 +206,7 @@ public class PipelineProcessor { outputFiles = newOutputFiles; } if (hasErrors) { - logger.error("Errors occurred during processing. Log: {}", logStream.toString()); + log.error("Errors occurred during processing. Log: {}", logStream.toString()); } return outputFiles; @@ -310,7 +308,7 @@ public class PipelineProcessor { List generateInputFiles(File[] files) throws Exception { if (files == null || files.length == 0) { - logger.info("No files"); + log.info("No files"); return null; } @@ -318,7 +316,7 @@ public class PipelineProcessor { for (File file : files) { Path path = Paths.get(file.getAbsolutePath()); - logger.info("Reading file: " + path); // debug statement + log.info("Reading file: " + path); // debug statement if (Files.exists(path)) { Resource fileResource = @@ -330,16 +328,16 @@ public class PipelineProcessor { }; outputFiles.add(fileResource); } else { - logger.info("File not found: " + path); + log.info("File not found: " + path); } } - logger.info("Files successfully loaded. Starting processing..."); + log.info("Files successfully loaded. Starting processing..."); return outputFiles; } List generateInputFiles(MultipartFile[] files) throws Exception { if (files == null || files.length == 0) { - logger.info("No files"); + log.info("No files"); return null; } @@ -355,7 +353,7 @@ public class PipelineProcessor { }; outputFiles.add(fileResource); } - logger.info("Files successfully loaded. Starting processing..."); + log.info("Files successfully loaded. Starting processing..."); return outputFiles; } @@ -369,7 +367,7 @@ public class PipelineProcessor { } private List unzip(byte[] data) throws IOException { - logger.info("Unzipping data of length: {}", data.length); + log.info("Unzipping data of length: {}", data.length); List unzippedFiles = new ArrayList<>(); try (ByteArrayInputStream bais = new ByteArrayInputStream(data); @@ -396,7 +394,7 @@ public class PipelineProcessor { // If the unzipped file is a zip file, unzip it if (isZip(baos.toByteArray())) { - logger.info("File {} is a zip file. Unzipping...", filename); + log.info("File {} is a zip file. Unzipping...", filename); unzippedFiles.addAll(unzip(baos.toByteArray())); } else { unzippedFiles.add(fileResource); @@ -404,7 +402,7 @@ public class PipelineProcessor { } } - logger.info("Unzipping completed. {} files were unzipped.", unzippedFiles.size()); + log.info("Unzipping completed. {} files were unzipped.", unzippedFiles.size()); return unzippedFiles; } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java b/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java index 27262feb..2058b55a 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/CertSignController.java @@ -63,8 +63,6 @@ import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.bouncycastle.pkcs.PKCSException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.http.ResponseEntity; @@ -78,17 +76,17 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.security.SignPDFWithCertRequest; import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/security") +@Slf4j @Tag(name = "Security", description = "Security APIs") public class CertSignController { - private static final Logger logger = LoggerFactory.getLogger(CertSignController.class); - static { Security.addProvider(new BouncyCastleProvider()); } @@ -108,7 +106,7 @@ public class CertSignController { logoFile = Files.createTempFile("signature", ".png").toFile(); FileUtils.copyInputStreamToFile(is, logoFile); } catch (IOException e) { - logger.error("Failed to load image signature file"); + log.error("Failed to load image signature file"); throw e; } } @@ -212,7 +210,9 @@ public class CertSignController { @Operation( summary = "Sign PDF with a Digital Certificate", description = - "This endpoint accepts a PDF file, a digital certificate and related information to sign the PDF. It then returns the digitally signed PDF file. Input:PDF Output:PDF Type:SISO") + "This endpoint accepts a PDF file, a digital certificate and related information to sign" + + " the PDF. It then returns the digitally signed PDF file. Input:PDF Output:PDF" + + " Type:SISO") public ResponseEntity signPDFWithCert(@ModelAttribute SignPDFWithCertRequest request) throws Exception { MultipartFile pdf = request.getFileInput(); @@ -308,7 +308,7 @@ public class CertSignController { } doc.saveIncremental(output); } catch (Exception e) { - logger.error("exception", e); + log.error("exception", e); } } diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java b/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java index d6950e95..5e534934 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java @@ -56,8 +56,6 @@ import org.apache.xmpbox.XMPMetadata; import org.apache.xmpbox.xml.DomXmpParser; import org.apache.xmpbox.xml.XmpParsingException; import org.apache.xmpbox.xml.XmpSerializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -73,16 +71,16 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.api.PDFFile; import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/security") +@Slf4j @Tag(name = "Security", description = "Security APIs") public class GetInfoOnPDF { - private static final Logger logger = LoggerFactory.getLogger(GetInfoOnPDF.class); - static ObjectMapper objectMapper = new ObjectMapper(); @PostMapping(consumes = "multipart/form-data", value = "/get-info-on-pdf") @@ -224,7 +222,7 @@ public class GetInfoOnPDF { javascriptArray.add(jsNode); } } catch (IOException e) { - logger.error("exception", e); + log.error("exception", e); } } } @@ -257,7 +255,7 @@ public class GetInfoOnPDF { } } catch (Exception e) { // TODO Auto-generated catch block - logger.error("exception", e); + log.error("exception", e); } boolean isPdfACompliant = checkForStandard(pdfBoxDoc, "PDF/A"); @@ -309,7 +307,7 @@ public class GetInfoOnPDF { new XmpSerializer().serialize(xmpMeta, os, true); xmpString = new String(os.toByteArray(), StandardCharsets.UTF_8); } catch (XmpParsingException | IOException e) { - logger.error("exception", e); + log.error("exception", e); } } @@ -585,7 +583,7 @@ public class GetInfoOnPDF { MediaType.APPLICATION_JSON); } catch (Exception e) { - logger.error("exception", e); + log.error("exception", e); } return null; } @@ -701,7 +699,7 @@ public class GetInfoOnPDF { Exception e) { // Catching general exception for brevity, ideally you'd catch specific // exceptions. - logger.error("exception", e); + log.error("exception", e); } return false; diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java b/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java index d738ae79..6a89a071 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/PasswordController.java @@ -5,8 +5,6 @@ import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.encryption.AccessPermission; import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -29,8 +27,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "Security", description = "Security APIs") public class PasswordController { - private static final Logger logger = LoggerFactory.getLogger(PasswordController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -42,7 +38,8 @@ public class PasswordController { @Operation( summary = "Remove password from a PDF file", description = - "This endpoint removes the password from a protected PDF file. Users need to provide the existing password. Input:PDF Output:PDF Type:SISO") + "This endpoint removes the password from a protected PDF file. Users need to provide the" + + " existing password. Input:PDF Output:PDF Type:SISO") public ResponseEntity removePassword(@ModelAttribute PDFPasswordRequest request) throws IOException { MultipartFile fileInput = request.getFileInput(); @@ -60,7 +57,8 @@ public class PasswordController { @Operation( summary = "Add password to a PDF file", description = - "This endpoint adds password protection to a PDF file. Users can specify a set of permissions that should be applied to the file. Input:PDF Output:PDF") + "This endpoint adds password protection to a PDF file. Users can specify a set of" + + " permissions that should be applied to the file. Input:PDF Output:PDF") public ResponseEntity addPassword(@ModelAttribute AddPasswordRequest request) throws IOException { MultipartFile fileInput = request.getFileInput(); diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java b/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java index d9e1e4ca..aab4aecc 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java @@ -8,8 +8,6 @@ import java.util.List; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -22,6 +20,7 @@ import io.github.pixee.security.Filenames; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.PDFText; import stirling.software.SPDF.model.api.security.RedactPdfRequest; import stirling.software.SPDF.pdf.TextFinder; @@ -31,11 +30,10 @@ import stirling.software.SPDF.utils.WebResponseUtils; @RestController @RequestMapping("/api/v1/security") +@Slf4j @Tag(name = "Security", description = "Security APIs") public class RedactController { - private static final Logger logger = LoggerFactory.getLogger(RedactController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -47,7 +45,8 @@ public class RedactController { @Operation( summary = "Redacts listOfText in a PDF document", description = - "This operation takes an input PDF file and redacts the provided listOfText. Input:PDF, Output:PDF, Type:SISO") + "This operation takes an input PDF file and redacts the provided listOfText. Input:PDF," + + " Output:PDF, Type:SISO") public ResponseEntity redactPdf(@ModelAttribute RedactPdfRequest request) throws Exception { MultipartFile file = request.getFileInput(); @@ -68,7 +67,7 @@ public class RedactController { } redactColor = Color.decode(colorString); } catch (NumberFormatException e) { - logger.warn("Invalid color string provided. Using default color BLACK for redaction."); + log.warn("Invalid color string provided. Using default color BLACK for redaction."); redactColor = Color.BLACK; } diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/RemoveCertSignController.java b/src/main/java/stirling/software/SPDF/controller/api/security/RemoveCertSignController.java index bd4c8c3d..9d1c78e9 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/RemoveCertSignController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/RemoveCertSignController.java @@ -8,8 +8,6 @@ import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; import org.apache.pdfbox.pdmodel.interactive.form.PDField; import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; @@ -31,8 +29,6 @@ import stirling.software.SPDF.utils.WebResponseUtils; @Tag(name = "Security", description = "Security APIs") public class RemoveCertSignController { - private static final Logger logger = LoggerFactory.getLogger(RemoveCertSignController.class); - private final CustomPDDocumentFactory pdfDocumentFactory; @Autowired @@ -44,7 +40,8 @@ public class RemoveCertSignController { @Operation( summary = "Remove digital signature from PDF", description = - "This endpoint accepts a PDF file and returns the PDF file without the digital signature. Input: PDF, Output: PDF") + "This endpoint accepts a PDF file and returns the PDF file without the digital signature." + + " Input: PDF, Output: PDF") public ResponseEntity removeCertSignPDF(@ModelAttribute PDFFile request) throws Exception { MultipartFile pdf = request.getFileInput(); diff --git a/src/main/java/stirling/software/SPDF/controller/web/GeneralWebController.java b/src/main/java/stirling/software/SPDF/controller/web/GeneralWebController.java index 99e29bde..7845fc29 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/GeneralWebController.java +++ b/src/main/java/stirling/software/SPDF/controller/web/GeneralWebController.java @@ -15,8 +15,6 @@ import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; @@ -31,16 +29,16 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface; import stirling.software.SPDF.model.SignatureFile; import stirling.software.SPDF.service.SignatureService; @Controller @Tag(name = "General", description = "General APIs") +@Slf4j public class GeneralWebController { - private static final Logger logger = LoggerFactory.getLogger(GeneralWebController.class); - @GetMapping("/pipeline") @Hidden public String pipelineForm(Model model) { @@ -82,7 +80,7 @@ public class GeneralWebController { } } catch (IOException e) { - logger.error("exception", e); + log.error("exception", e); } } if (pipelineConfigsWithNames.size() == 0) { diff --git a/src/main/java/stirling/software/SPDF/controller/web/HomeWebController.java b/src/main/java/stirling/software/SPDF/controller/web/HomeWebController.java index 41dca2fd..dc67be74 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/HomeWebController.java +++ b/src/main/java/stirling/software/SPDF/controller/web/HomeWebController.java @@ -6,8 +6,6 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; @@ -22,14 +20,14 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.Hidden; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.Dependency; @Controller +@Slf4j public class HomeWebController { - private static final Logger logger = LoggerFactory.getLogger(HomeWebController.class); - @GetMapping("/about") @Hidden public String gameForm(Model model) { @@ -50,7 +48,7 @@ public class HomeWebController { mapper.readValue(json, new TypeReference>>() {}); model.addAttribute("dependencies", data.get("dependencies")); } catch (IOException e) { - logger.error("exception", e); + log.error("exception", e); } return "licenses"; } diff --git a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java index 703b5ee6..fd7c278b 100644 --- a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java +++ b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java @@ -122,18 +122,19 @@ public class ApplicationProperties { @Getter @Setter + @ToString public static class SAML2 { private Boolean enabled = false; private Boolean autoCreateUser = false; private Boolean blockRegistration = false; private String registrationId = "stirling"; - private String idpMetadataUri; + @ToString.Exclude private String idpMetadataUri; private String idpSingleLogoutUrl; private String idpSingleLoginUrl; private String idpIssuer; private String idpCert; - private String privateKey; - private String spCert; + @ToString.Exclude private String privateKey; + @ToString.Exclude private String spCert; public InputStream getIdpMetadataUri() throws IOException { if (idpMetadataUri.startsWith("classpath:")) { diff --git a/src/main/java/stirling/software/SPDF/model/api/PDFWithPageNums.java b/src/main/java/stirling/software/SPDF/model/api/PDFWithPageNums.java index 173bde0b..4eaabe87 100644 --- a/src/main/java/stirling/software/SPDF/model/api/PDFWithPageNums.java +++ b/src/main/java/stirling/software/SPDF/model/api/PDFWithPageNums.java @@ -5,8 +5,6 @@ import java.util.List; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.media.Schema; @@ -14,18 +12,20 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.utils.GeneralUtils; @Data @NoArgsConstructor +@Slf4j @EqualsAndHashCode(callSuper = true) public class PDFWithPageNums extends PDFFile { - private static final Logger logger = LoggerFactory.getLogger(PDFWithPageNums.class); - @Schema( description = - "The pages to select, Supports ranges (e.g., '1,3,5-9'), or 'all' or functions in the format 'an+b' where 'a' is the multiplier of the page number 'n', and 'b' is a constant (e.g., '2n+1', '3n', '6n-5')\"") + "The pages to select, Supports ranges (e.g., '1,3,5-9'), or 'all' or functions in the" + + " format 'an+b' where 'a' is the multiplier of the page number 'n', and 'b' is a" + + " constant (e.g., '2n+1', '3n', '6n-5')\"") private String pageNumbers; @Hidden @@ -35,7 +35,7 @@ public class PDFWithPageNums extends PDFFile { pageCount = Loader.loadPDF(getFileInput().getBytes()).getNumberOfPages(); } catch (IOException e) { // TODO Auto-generated catch block - logger.error("exception", e); + log.error("exception", e); } return GeneralUtils.parsePageList(pageNumbers, pageCount, zeroCount); } diff --git a/src/main/java/stirling/software/SPDF/service/CustomPDDocumentFactory.java b/src/main/java/stirling/software/SPDF/service/CustomPDDocumentFactory.java index 0807e0d1..040e65d1 100644 --- a/src/main/java/stirling/software/SPDF/service/CustomPDDocumentFactory.java +++ b/src/main/java/stirling/software/SPDF/service/CustomPDDocumentFactory.java @@ -7,20 +7,18 @@ import java.io.InputStream; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.PdfMetadata; import stirling.software.SPDF.model.api.PDFFile; @Component +@Slf4j public class CustomPDDocumentFactory { - private static final Logger logger = LoggerFactory.getLogger(CustomPDDocumentFactory.class); - private final PdfMetadataService pdfMetadataService; @Autowired @@ -133,10 +131,10 @@ public class CustomPDDocumentFactory { private PDDocument removezeropassword(PDDocument document) throws IOException { if (document.isEncrypted()) { try { - logger.info("Removing security from the source document"); + log.info("Removing security from the source document"); document.setAllSecurityToBeRemoved(true); } catch (Exception e) { - logger.warn("Cannot decrypt the pdf"); + log.warn("Cannot decrypt the pdf"); } } return document; diff --git a/src/main/java/stirling/software/SPDF/utils/FileMonitor.java b/src/main/java/stirling/software/SPDF/utils/FileMonitor.java index 6d96958c..493ddd6e 100644 --- a/src/main/java/stirling/software/SPDF/utils/FileMonitor.java +++ b/src/main/java/stirling/software/SPDF/utils/FileMonitor.java @@ -9,16 +9,17 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import lombok.extern.slf4j.Slf4j; + @Component +@Slf4j public class FileMonitor { - private static final Logger logger = LoggerFactory.getLogger(FileMonitor.class); + private final Map path2KeyMapping; private final Set newlyDiscoveredFiles; private final ConcurrentHashMap.KeySetView readyForProcessingFiles; @@ -53,7 +54,7 @@ public class FileMonitor { private void recursivelyRegisterEntry(Path dir) throws IOException { WatchKey key = dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); path2KeyMapping.put(dir, key); - logger.info("Registered directory: {}", dir); + log.info("Registered directory: {}", dir); try (Stream directoryVisitor = Files.walk(dir, 1)) { final Iterator iterator = directoryVisitor.iterator(); @@ -80,14 +81,13 @@ public class FileMonitor { readyForProcessingFiles.clear(); if (path2KeyMapping.isEmpty()) { - logger.warn( - "not monitoring any directory, even the root directory itself: {}", rootDir); + log.warn("not monitoring any directory, even the root directory itself: {}", rootDir); if (Files.exists( rootDir)) { // if the root directory exists, re-register the root directory try { recursivelyRegisterEntry(rootDir); } catch (IOException e) { - logger.error("unable to register monitoring", e); + log.error("unable to register monitoring", e); } } } @@ -122,7 +122,7 @@ public class FileMonitor { handleFileModification(relativePathFromRoot); } } catch (Exception e) { - logger.error("Error while processing file: {}", path, e); + log.error("Error while processing file: {}", path, e); } }); diff --git a/src/main/java/stirling/software/SPDF/utils/GeneralUtils.java b/src/main/java/stirling/software/SPDF/utils/GeneralUtils.java index bb3bbc04..73f5167e 100644 --- a/src/main/java/stirling/software/SPDF/utils/GeneralUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/GeneralUtils.java @@ -27,8 +27,6 @@ import org.simpleyaml.configuration.file.YamlFile; import org.simpleyaml.configuration.file.YamlFileWrapper; import org.simpleyaml.configuration.implementation.SimpleYamlImplementation; import org.simpleyaml.configuration.implementation.snakeyaml.lib.DumperOptions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.web.multipart.MultipartFile; import com.fathzer.soft.javaluator.DoubleEvaluator; @@ -36,9 +34,10 @@ import com.fathzer.soft.javaluator.DoubleEvaluator; import io.github.pixee.security.HostValidator; import io.github.pixee.security.Urls; -public class GeneralUtils { +import lombok.extern.slf4j.Slf4j; - private static final Logger logger = LoggerFactory.getLogger(GeneralUtils.class); +@Slf4j +public class GeneralUtils { public static File convertMultipartFileToFile(MultipartFile multipartFile) throws IOException { File tempFile = Files.createTempFile("temp", null).toFile(); @@ -301,7 +300,7 @@ public class GeneralUtils { try { Files.createDirectories(folder); } catch (IOException e) { - logger.error("exception", e); + log.error("exception", e); return false; } } diff --git a/src/main/java/stirling/software/SPDF/utils/ImageProcessingUtils.java b/src/main/java/stirling/software/SPDF/utils/ImageProcessingUtils.java index 4eba6c25..24cb72eb 100644 --- a/src/main/java/stirling/software/SPDF/utils/ImageProcessingUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/ImageProcessingUtils.java @@ -12,8 +12,6 @@ import java.nio.ByteBuffer; import javax.imageio.ImageIO; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.web.multipart.MultipartFile; import com.drew.imaging.ImageMetadataReader; @@ -22,9 +20,10 @@ import com.drew.metadata.Metadata; import com.drew.metadata.MetadataException; import com.drew.metadata.exif.ExifSubIFDDirectory; -public class ImageProcessingUtils { +import lombok.extern.slf4j.Slf4j; - private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class); +@Slf4j +public class ImageProcessingUtils { static BufferedImage convertColorType(BufferedImage sourceImage, String colorType) { BufferedImage convertedImage; @@ -97,7 +96,7 @@ public class ImageProcessingUtils { case 8: return 270; default: - logger.warn("Unknown orientation tag: {}", orientationTag); + log.warn("Unknown orientation tag: {}", orientationTag); return 0; } } catch (ImageProcessingException | MetadataException e) { diff --git a/src/main/java/stirling/software/SPDF/utils/PDFToFile.java b/src/main/java/stirling/software/SPDF/utils/PDFToFile.java index 1a1957cf..8827b19b 100644 --- a/src/main/java/stirling/software/SPDF/utils/PDFToFile.java +++ b/src/main/java/stirling/software/SPDF/utils/PDFToFile.java @@ -14,8 +14,6 @@ import java.util.zip.ZipOutputStream; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -23,10 +21,11 @@ import org.springframework.web.multipart.MultipartFile; import io.github.pixee.security.Filenames; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult; +@Slf4j public class PDFToFile { - private static final Logger logger = LoggerFactory.getLogger(PDFToFile.class); public ResponseEntity processPdfToHtml(MultipartFile inputFile) throws IOException, InterruptedException { @@ -77,12 +76,12 @@ public class PDFToFile { try (FileInputStream fis = new FileInputStream(outputFile)) { IOUtils.copy(fis, zipOutputStream); } catch (IOException e) { - logger.error("Exception writing zip entry", e); + log.error("Exception writing zip entry", e); } zipOutputStream.closeEntry(); } } catch (IOException e) { - logger.error("Exception writing zip", e); + log.error("Exception writing zip", e); } fileBytes = byteArrayOutputStream.toByteArray(); @@ -174,13 +173,13 @@ public class PDFToFile { try (FileInputStream fis = new FileInputStream(outputFile)) { IOUtils.copy(fis, zipOutputStream); } catch (IOException e) { - logger.error("Exception writing zip entry", e); + log.error("Exception writing zip entry", e); } zipOutputStream.closeEntry(); } } catch (IOException e) { - logger.error("Exception writing zip", e); + log.error("Exception writing zip", e); } fileBytes = byteArrayOutputStream.toByteArray(); diff --git a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java index 8ccd2942..fb2ffd59 100644 --- a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java @@ -30,18 +30,16 @@ import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.text.PDFTextStripper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.web.multipart.MultipartFile; import io.github.pixee.security.Filenames; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.service.CustomPDDocumentFactory; +@Slf4j public class PdfUtils { - private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class); - public static PDRectangle textToPageSize(String size) { switch (size.toUpperCase()) { case "A0": @@ -310,7 +308,7 @@ public class PdfUtils { } // Log that the image was successfully written to the byte array - logger.info("Image successfully written to byte array"); + log.info("Image successfully written to byte array"); } else { // Zip the images and return as byte array try (ZipOutputStream zos = new ZipOutputStream(baos)) { @@ -330,13 +328,13 @@ public class PdfUtils { } } // Log that the images were successfully written to the byte array - logger.info("Images successfully written to byte array as a zip"); + log.info("Images successfully written to byte array as a zip"); } } return baos.toByteArray(); } catch (IOException e) { // Log an error message if there is an issue converting the PDF to an image - logger.error("Error converting PDF to image", e); + log.error("Error converting PDF to image", e); throw e; } } @@ -421,7 +419,7 @@ public class PdfUtils { } ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); doc.save(byteArrayOutputStream); - logger.info("PDF successfully saved to byte array"); + log.info("PDF successfully saved to byte array"); return byteArrayOutputStream.toByteArray(); } } @@ -471,7 +469,7 @@ public class PdfUtils { image.getHeight() * scaleFactor); } } catch (IOException e) { - logger.error("Error adding image to PDF", e); + log.error("Error adding image to PDF", e); throw e; } } @@ -498,20 +496,20 @@ public class PdfUtils { PDImageXObject image = PDImageXObject.createFromByteArray(document, imageBytes, ""); // Draw the image onto the page at the specified x and y coordinates contentStream.drawImage(image, x, y); - logger.info("Image successfully overlayed onto PDF"); + log.info("Image successfully overlayed onto PDF"); if (!everyPage && i == 0) { break; } } catch (IOException e) { // Log an error message if there is an issue overlaying the image onto the PDF - logger.error("Error overlaying image onto PDF", e); + log.error("Error overlaying image onto PDF", e); throw e; } } // Create a ByteArrayOutputStream to save the PDF to ByteArrayOutputStream baos = new ByteArrayOutputStream(); document.save(baos); - logger.info("PDF successfully saved to byte array"); + log.info("PDF successfully saved to byte array"); return baos.toByteArray(); } diff --git a/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java b/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java index e99cd70a..15eab3b2 100644 --- a/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java +++ b/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java @@ -13,17 +13,14 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import io.github.pixee.security.BoundedLineReader; +import lombok.extern.slf4j.Slf4j; import stirling.software.SPDF.model.ApplicationProperties; +@Slf4j public class ProcessExecutor { - private static final Logger logger = LoggerFactory.getLogger(ProcessExecutor.class); - private static ApplicationProperties applicationProperties = new ApplicationProperties(); public enum Processes { @@ -160,7 +157,7 @@ public class ProcessExecutor { semaphore.acquire(); try { - logger.info("Running command: " + String.join(" ", command)); + log.info("Running command: " + String.join(" ", command)); ProcessBuilder processBuilder = new ProcessBuilder(command); // Use the working directory if it's set @@ -187,13 +184,12 @@ public class ProcessExecutor { errorReader, 5_000_000)) != null) { errorLines.add(line); - if (liveUpdates) logger.info(line); + if (liveUpdates) log.info(line); } } catch (InterruptedIOException e) { - logger.warn( - "Error reader thread was interrupted due to timeout."); + log.warn("Error reader thread was interrupted due to timeout."); } catch (IOException e) { - logger.error("exception", e); + log.error("exception", e); } }); @@ -211,13 +207,12 @@ public class ProcessExecutor { outputReader, 5_000_000)) != null) { outputLines.add(line); - if (liveUpdates) logger.info(line); + if (liveUpdates) log.info(line); } } catch (InterruptedIOException e) { - logger.warn( - "Error reader thread was interrupted due to timeout."); + log.warn("Error reader thread was interrupted due to timeout."); } catch (IOException e) { - logger.error("exception", e); + log.error("exception", e); } }); @@ -244,7 +239,7 @@ public class ProcessExecutor { String outputMessage = String.join("\n", outputLines); messages += outputMessage; if (!liveUpdates) { - logger.info("Command output:\n" + outputMessage); + log.info("Command output:\n" + outputMessage); } } @@ -252,7 +247,7 @@ public class ProcessExecutor { String errorMessage = String.join("\n", errorLines); messages += errorMessage; if (!liveUpdates) { - logger.warn("Command error output:\n" + errorMessage); + log.warn("Command error output:\n" + errorMessage); } if (exitCode != 0) { throw new IOException( diff --git a/src/main/resources/messages_ar_AR.properties b/src/main/resources/messages_ar_AR.properties index 954ce64b..b12a12ed 100644 --- a/src/main/resources/messages_ar_AR.properties +++ b/src/main/resources/messages_ar_AR.properties @@ -238,11 +238,13 @@ database.creationDate=تاريخ الإنشاء database.fileSize=حجم الملف database.deleteBackupFile=حذف ملف النسخ الاحتياطي database.importBackupFile=استيراد ملف النسخ الاحتياطي +database.createBackupFile=Create Backup File database.downloadBackupFile=تنزيل ملف النسخ الاحتياطي database.info_1=عند استيراد البيانات، من الضروري ضمان الهيكل الصحيح. إذا كنت غير متأكد مما تفعله، اطلب المشورة والدعم من محترف. يمكن أن يؤدي الخطأ في الهيكل إلى حدوث أعطال في التطبيق، حتى عدم القدرة على تشغيل التطبيق بالكامل. database.info_2=لا يهم اسم الملف عند التحميل. سيتم إعادة تسميته بعد ذلك لاتباع التنسيق backup_user_yyyyMMddHHmm.sql، مما يضمن اتساق تسمية متناسق. database.submit=استيراد النسخة الاحتياطية database.importIntoDatabaseSuccessed=تم استيراد قاعدة البيانات بنجاح +database.backupCreated=Database backup successful database.fileNotFound=لم يتم العثور على الملف database.fileNullOrEmpty=يجب ألا يكون الملف فارغًا أو خاليًا database.failedImportFile=فشل استيراد الملف diff --git a/src/main/resources/messages_az_AZ.properties b/src/main/resources/messages_az_AZ.properties index dcffafa6..9a4cae6a 100644 --- a/src/main/resources/messages_az_AZ.properties +++ b/src/main/resources/messages_az_AZ.properties @@ -238,11 +238,13 @@ database.creationDate=Yaradılma tarixi database.fileSize=Fayl Ölçüsü database.deleteBackupFile=Yedək Faylını Sil database.importBackupFile=Yedək Faylını Daxil Et +database.createBackupFile=Create Backup File database.downloadBackupFile=Yedək Faylını Yüklə database.info_1=Məlumatı daxil edərkən doğru strukturun mövcudluğundan əmin olmaq vacibdir. Əgər nə etdiyinizdən əmin deyilsinizsə, professional birindən məsləhət və yardım alın. Strukturdakı xəta proqramdakı nasazlıqlardan proqramı çalışdırma qabiliyyətinin tamamilə aradan qalxmasına qədər bir sıra problemlərə səbəb ola bilər. database.info_2=Faylın adı fayl yüklənərkən önəmli deyildir. Faylın adı sonradan sabit adlandırmanın varlığından əmin olmaq məqsədilə backup_user_yyyyMMddHHmm.sql tərzində formata dəyişdiriləcəkdir. database.submit=Yedəkləməni Daxil Et database.importIntoDatabaseSuccessed=Verilənlər bazasına daxil etmə uğurla nəticələndi +database.backupCreated=Database backup successful database.fileNotFound=Fayl Tapılmadı database.fileNullOrEmpty=Fayl boş və ya "null" olmamalıdır database.failedImportFile=Faylı daxil etmək alınmadı diff --git a/src/main/resources/messages_bg_BG.properties b/src/main/resources/messages_bg_BG.properties index 8c6b510f..fb4796e5 100644 --- a/src/main/resources/messages_bg_BG.properties +++ b/src/main/resources/messages_bg_BG.properties @@ -238,11 +238,13 @@ database.creationDate=Дата на създаване database.fileSize=Размер на файла database.deleteBackupFile=Изтриване на архивен файл database.importBackupFile=Импортиране на архивен файл +database.createBackupFile=Create Backup File database.downloadBackupFile=Изтеглете архивен файл database.info_1=Когато импортирате данни, е от решаващо значение да осигурите правилната структура. Ако не сте сигурни в това, което правите, потърсете съвет и подкрепа от професионалист. Грешка в структурата може да причини неизправност на приложението, включително пълна невъзможност за стартиране на приложението. database.info_2=Името на файла няма значение при качване. След това ще бъде преименуван, за да следва формата backup_user_yyyyMMddHHmm.sql, осигурявайки последователна конвенция за именуване. database.submit=Импортиране на резервно копие database.importIntoDatabaseSuccessed=Импортирането в базата данни бе успешно +database.backupCreated=Database backup successful database.fileNotFound=Файлът не е намерен database.fileNullOrEmpty=Файлът не трябва да е нулев или празен database.failedImportFile=Неуспешно импортиране на файл diff --git a/src/main/resources/messages_ca_CA.properties b/src/main/resources/messages_ca_CA.properties index 2cf560b1..96e429a3 100644 --- a/src/main/resources/messages_ca_CA.properties +++ b/src/main/resources/messages_ca_CA.properties @@ -238,11 +238,13 @@ database.creationDate=Data de Creació database.fileSize=Mida del Fitxer database.deleteBackupFile=Elimina el Fitxer de Còpia de Seguretat database.importBackupFile=Importa el Fitxer de Còpia de Seguretat +database.createBackupFile=Create Backup File database.downloadBackupFile=Descarrega el Fitxer de Còpia de Seguretat database.info_1=Quan importis dades, és crucial assegurar-se que l'estructura sigui correcta. Si no estàs segur del que fas, busca l'assessorament d'un professional. Un error en l'estructura pot causar malfuncionaments de l'aplicació, fins i tot impossibilitar-ne l'execució. database.info_2=El nom del fitxer no importa quan es puja. Es renombrarà després per seguir el format backup_user_yyyyMMddHHmm.sql, assegurant una convenció de nomenclatura consistent. database.submit=Importa la Còpia de Seguretat database.importIntoDatabaseSuccessed=Importació a la base de dades completada amb èxit +database.backupCreated=Database backup successful database.fileNotFound=Fitxer no trobat database.fileNullOrEmpty=El fitxer no ha de ser nul o buit database.failedImportFile=Error en la importació del fitxer diff --git a/src/main/resources/messages_cs_CZ.properties b/src/main/resources/messages_cs_CZ.properties index fbf4b21f..553ec40e 100644 --- a/src/main/resources/messages_cs_CZ.properties +++ b/src/main/resources/messages_cs_CZ.properties @@ -238,11 +238,13 @@ database.creationDate=Datum vytvoření database.fileSize=Velikost souboru database.deleteBackupFile=Smazat záložní soubor database.importBackupFile=Import zálohy souboru +database.createBackupFile=Create Backup File database.downloadBackupFile=Stáhnout zálohový soubor database.info_1=Při importu dat je důležité zajistit správnou strukturu. Pokud jste nejistí, jak se chovat, hledajte konzultaci a podporu od profesionala. Chyba v struktuře může vést k selhání aplikace, dokonce i k tomu, že by aplikace nemohla být spuštěna. database.info_2=Název souboru nezáleží při nahrávání. Bude jeho zpětně znovu pojmenován podle formáту backup_user_yyyyMMddHHmm.sql, což zajišťuje konzistentní pravidlo označení. database.submit=Import zálohy database.importIntoDatabaseSuccessed=Import do databáze byl úspěšný +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=Soubor nemůže být null nebo prázdný database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_da_DK.properties b/src/main/resources/messages_da_DK.properties index ad383ff8..9ab36d58 100644 --- a/src/main/resources/messages_da_DK.properties +++ b/src/main/resources/messages_da_DK.properties @@ -238,11 +238,13 @@ database.creationDate=Oprettelsesdato database.fileSize=Filstørrelse database.deleteBackupFile=Slet Backup-fil database.importBackupFile=Importér Backup-fil +database.createBackupFile=Create Backup File database.downloadBackupFile=Download Backup-fil database.info_1=Ved import af data er det afgørende at sikre den korrekte struktur. Hvis du er usikker på, hvad du gør, søg råd og støtte fra en professionel. En fejl i strukturen kan forårsage applikationsfejl, op til og med fuldstændig manglende evne til at køre applikationen. database.info_2=Filnavnet er ligegyldigt ved upload. Det vil blive omdøbt bagefter for at følge formatet backup_user_yyyyMMddHHmm.sql, hvilket sikrer en konsistent navngivningskonvention. database.submit=Importér Backup database.importIntoDatabaseSuccessed=Import i database lykkedes +database.backupCreated=Database backup successful database.fileNotFound=Fil ikke fundet database.fileNullOrEmpty=Fil må ikke være null eller tom database.failedImportFile=Kunne ikke importere fil diff --git a/src/main/resources/messages_de_DE.properties b/src/main/resources/messages_de_DE.properties index 06de0a84..3681c221 100644 --- a/src/main/resources/messages_de_DE.properties +++ b/src/main/resources/messages_de_DE.properties @@ -238,11 +238,13 @@ database.creationDate=Erstellungsdatum database.fileSize=Dateigröße database.deleteBackupFile=Sicherungsdatei löschen database.importBackupFile=Sicherungsdatei importieren +database.createBackupFile=Sicherungsdatei erstellen database.downloadBackupFile=Sicherungsdatei herunterladen database.info_1=Beim Importieren der Daten ist es von größter Bedeutung, die korrekte Struktur zu gewährleisten. Wenn Sie nicht sicher sind, was Sie tun, suchen Sie Rat und Unterstützung von einem Fachmann. Ein Fehler in der Struktur kann zu Fehlfunktionen der Anwendung führen, bis hin zur vollständigen Nicht-Lauffähigkeit der Anwendung. database.info_2=Der Dateiname spielt beim Hochladen keine Rolle. Dieser wird nachträglich in das Format backup_user_yyyyMMddHHmm.sql geändert, um eine einheitliche Benennung zu gewährleisten. database.submit=Sicherungsdatei importieren database.importIntoDatabaseSuccessed=Import in die Datenbank erfolgreich +database.backupCreated=Datenbanksicherung erfolgreich database.fileNotFound=Datei nicht gefunden database.fileNullOrEmpty=Datei darf nicht null oder leer sein database.failedImportFile=Dateiimport fehlgeschlagen @@ -966,14 +968,14 @@ multiTool.undo=Rückgängig machen multiTool.redo=Wiederherstellen #decrypt -decrypt.passwordPrompt=This file is password-protected. Please enter the password: -decrypt.cancelled=Operation cancelled for PDF: {0} -decrypt.noPassword=No password provided for encrypted PDF: {0} -decrypt.invalidPassword=Please try again with the correct password. -decrypt.invalidPasswordHeader=Incorrect password or unsupported encryption for PDF: {0} -decrypt.unexpectedError=There was an error processing the file. Please try again. -decrypt.serverError=Server error while decrypting: {0} -decrypt.success=File decrypted successfully. +decrypt.passwordPrompt=Diese Datei ist passwortgeschützt. Bitte geben Sie das Passwort ein: +decrypt.cancelled=Vorgang für PDF abgebrochen: {0} +decrypt.noPassword=Kein Passwort für verschlüsseltes PDF angegeben: {0} +decrypt.invalidPassword=Bitte versuchen Sie es erneut mit dem richtigen Passwort. +decrypt.invalidPasswordHeader=Falsches Passwort oder nicht unterstützte Verschlüsselung für PDF: {0} +decrypt.unexpectedError=Bei der Verarbeitung der Datei ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut. +decrypt.serverError=Serverfehler beim Entschlüsseln: {0} +decrypt.success=Datei erfolgreich entschlüsselt. #multiTool-advert multiTool-advert.message=Diese Funktion ist auch auf unserer PDF-Multitool-Seite verfügbar. Probieren Sie sie aus, denn sie bietet eine verbesserte Benutzeroberfläche und zusätzliche Funktionen! diff --git a/src/main/resources/messages_el_GR.properties b/src/main/resources/messages_el_GR.properties index 9c2e427d..cefb83e1 100644 --- a/src/main/resources/messages_el_GR.properties +++ b/src/main/resources/messages_el_GR.properties @@ -238,11 +238,13 @@ database.creationDate=Ημερομηνία δημιουργίας database.fileSize=Μέγεθος αρχείου database.deleteBackupFile=Διαγραφή Προγράμματος Ανασυγκρότησης database.importBackupFile=Εισάγωντας Προγράμματος Ανασυγκρότησης +database.createBackupFile=Create Backup File database.downloadBackupFile=Κατέβασμα Προγράμματος Ανασυγκρότησης database.info_1=Όταν εισάγετε δεδομένα, είναι σημαντικό να εξασφαλίσετε τη σωστή μορφοποίηση. Αν δεν είστε σίγουροι για το ποια πράγματα κάνετε, αιτήστε υποβολή και υποστήριξη από ευελίκτω. Μια σφάλμα στη μορφοποίηση μπορεί να προκαλέσει καταστάσεις λάθους στην εφαρμογή, αν όχι ολόκληρη την αποχώρηση της εφαρμογής. database.info_2=Το ονόμα του αρχείου δεν έχει σημασία όταν ξεκινάτε μια επέμβαση. Αλλαγήται αργότερα για να ακολουθήσει το σχήμα backup_ωςώντας_YYYYMMDDHHmm.sql, επιτρέποντας μια συνεχές κατάληψη ονόματος. database.submit=Εισάγωντας Προγράμματος Ανασυγκρότησης database.importIntoDatabaseSuccessed=Τελείωση εισαγωγής στη βάση δεδομένων. +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=Το αρχείο δεν μπορεί να είναι τυχόν ή κενό. database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index 4056f972..73e56c9d 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -238,11 +238,13 @@ database.creationDate=Creation Date database.fileSize=File Size database.deleteBackupFile=Delete Backup File database.importBackupFile=Import Backup File +database.createBackupFile=Create Backup File database.downloadBackupFile=Download Backup File database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.submit=Import Backup database.importIntoDatabaseSuccessed=Import into database successed +database.backupCreated=Database backup successful database.fileNotFound=File not found database.fileNullOrEmpty=File must not be null or empty database.failedImportFile=Failed to import file diff --git a/src/main/resources/messages_en_US.properties b/src/main/resources/messages_en_US.properties index dbd67e2c..99095e19 100644 --- a/src/main/resources/messages_en_US.properties +++ b/src/main/resources/messages_en_US.properties @@ -238,11 +238,13 @@ database.creationDate=Creation Date database.fileSize=File Size database.deleteBackupFile=Delete Backup File database.importBackupFile=Import Backup File +database.createBackupFile=Create Backup File database.downloadBackupFile=Download Backup File database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.submit=Import Backup database.importIntoDatabaseSuccessed=Import into database successed +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=File must not be null or empty database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_es_ES.properties b/src/main/resources/messages_es_ES.properties index d1c50df7..d21c2e60 100644 --- a/src/main/resources/messages_es_ES.properties +++ b/src/main/resources/messages_es_ES.properties @@ -238,11 +238,13 @@ database.creationDate=Fecha de creación database.fileSize=Tamaño de archivo database.deleteBackupFile=Eliminar archivo de copia de seguridad database.importBackupFile=Importar archivo de copia de seguridad +database.createBackupFile=Create Backup File database.downloadBackupFile=Descargar archivo de copia de seguridad database.info_1=Al importar datos, es fundamental garantizar la estructura correcta. Si no está seguro de lo que está haciendo, busque consejo y apoyo de un profesional. Un error en la estructura puede causar un mal funcionamiento de la aplicación, incluyendo la imposibilidad total de ejecutar la aplicación. database.info_2=El nombre del archivo no importa al cargarlo. Posteriormente se le cambiará el nombre para que siga el formato backup_user_yyyyMMddHHmm.sql, lo que garantiza una convención de nomenclatura coherente. database.submit=Importar Copia de Seguridad database.importIntoDatabaseSuccessed=Importación a la base de datos ha sido exitosa +database.backupCreated=Database backup successful database.fileNotFound=Archivo no encontrado database.fileNullOrEmpty=El archivo no debe ser nulo o vacío. database.failedImportFile=Archivo de importación fallido diff --git a/src/main/resources/messages_eu_ES.properties b/src/main/resources/messages_eu_ES.properties index aebd93e3..f5d65e4f 100644 --- a/src/main/resources/messages_eu_ES.properties +++ b/src/main/resources/messages_eu_ES.properties @@ -238,11 +238,13 @@ database.creationDate=Creation Date database.fileSize=File Size database.deleteBackupFile=Delete Backup File database.importBackupFile=Import Backup File +database.createBackupFile=Create Backup File database.downloadBackupFile=Download Backup File database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.submit=Import Backup database.importIntoDatabaseSuccessed=Import into database successed +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=File must not be null or empty database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_fa_IR.properties b/src/main/resources/messages_fa_IR.properties index 13c0a09d..ce7781da 100644 --- a/src/main/resources/messages_fa_IR.properties +++ b/src/main/resources/messages_fa_IR.properties @@ -238,11 +238,13 @@ database.creationDate=تاریخ ایجاد database.fileSize=اندازه فایل database.deleteBackupFile=حذف فایل پشتیبان database.importBackupFile=وارد کردن فایل پشتیبان +database.createBackupFile=Create Backup File database.downloadBackupFile=دانلود فایل پشتیبان database.info_1=هنگام وارد کردن داده‌ها، اطمینان از ساختار صحیح ضروری است. اگر مطمئن نیستید چه کاری انجام می‌دهید، از یک متخصص مشاوره و پشتیبانی دریافت کنید. خطا در ساختار می‌تواند باعث اختلالات برنامه شود، حتی تا حدی که برنامه به طور کامل قادر به اجرا نباشد. database.info_2=نام فایل هنگام آپلود مهم نیست. پس از آن برای پیروی از قالب backup_user_yyyyMMddHHmm.sql تغییر نام داده می‌شود تا یک قرارداد نام‌گذاری ثابت را تضمین کند. database.submit=وارد کردن پشتیبان database.importIntoDatabaseSuccessed=وارد کردن در پایگاه داده موفقیت‌آمیز بود +database.backupCreated=Database backup successful database.fileNotFound=فایل پیدا نشد database.fileNullOrEmpty=فایل نباید خالی یا تهی باشد database.failedImportFile=وارد کردن فایل ناموفق بود diff --git a/src/main/resources/messages_fr_FR.properties b/src/main/resources/messages_fr_FR.properties index 90f670c3..5f907ba9 100644 --- a/src/main/resources/messages_fr_FR.properties +++ b/src/main/resources/messages_fr_FR.properties @@ -238,11 +238,13 @@ database.creationDate=Date de Création database.fileSize=Taille du Fichier database.deleteBackupFile=Supprimer le fichier de sauvegarde database.importBackupFile=Importer le fichier de sauvegarde +database.createBackupFile=Create Backup File database.downloadBackupFile=Télécharger le fichier de sauvegarde database.info_1=Lors de l'importation des données, il est crucial de garantir la structure correcte. Si vous n'êtes pas sûr de ce que vous faites, sollicitez un avis et un soutien d'un professionnel. Une erreur dans la structure peut entraîner des dysfonctionnements de l'application, allant jusqu'à l'incapacité totale d'exécuter l'application. database.info_2=Le nom du fichier ne fait pas de différence lors de l'upload. Il sera renommé ultérieurement selon le format backup_user_yyyyMMddHHmm.sql, assurant ainsi une convention de nommage cohérente. database.submit=Importer la sauvegarde database.importIntoDatabaseSuccessed=Importation dans la base de données réussie +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=Fichier ne peut pas être null ou vide database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_ga_IE.properties b/src/main/resources/messages_ga_IE.properties index 087924ef..42ef0095 100644 --- a/src/main/resources/messages_ga_IE.properties +++ b/src/main/resources/messages_ga_IE.properties @@ -238,11 +238,13 @@ database.creationDate=Dáta Cruthaithe database.fileSize=Méid an Chomhaid database.deleteBackupFile=Scrios Comhad Cúltaca database.importBackupFile=Iompórtáil Comhad Cúltaca +database.createBackupFile=Create Backup File database.downloadBackupFile=Íoslódáil an comhad cúltaca database.info_1=Agus sonraí á n-allmhairiú, tá sé ríthábhachtach an struchtúr ceart a chinntiú. Mura bhfuil tú cinnte faoina bhfuil ar siúl agat, iarr comhairle agus tacaíocht ó ghairmí. Féadfaidh earráid sa struchtúr a bheith ina chúis le mífheidhmeanna iarratais, suas go dtí agus lena n-áirítear an neamhábaltacht iomlán an t-iarratas a rith. database.info_2=Ní hionann ainm an chomhaid agus é á uaslódáil. Déanfar é a athainmniú ina dhiaidh sin chun an fhormáid backup_user_yyyyMMddHHmm.sql a leanúint, ag cinntiú go bhfuil coinbhinsiún ainmniúcháin comhsheasmhach ann. database.submit=Iompórtáil Cúltaca database.importIntoDatabaseSuccessed=D'éirigh leis an allmhairiú isteach sa bhunachar sonraí +database.backupCreated=Database backup successful database.fileNotFound=Comhad gan aimsiú database.fileNullOrEmpty=Níor cheart go mbeadh an comhad ar neamhní nó folamh database.failedImportFile=Theip ar iompórtáil an chomhaid diff --git a/src/main/resources/messages_hi_IN.properties b/src/main/resources/messages_hi_IN.properties index 957238e0..581f04b1 100644 --- a/src/main/resources/messages_hi_IN.properties +++ b/src/main/resources/messages_hi_IN.properties @@ -238,11 +238,13 @@ database.creationDate=Creation Date database.fileSize=File Size database.deleteBackupFile=Delete Backup File database.importBackupFile=Import Backup File +database.createBackupFile=Create Backup File database.downloadBackupFile=Download Backup File database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.submit=Import Backup database.importIntoDatabaseSuccessed=Import into database successed +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=File must not be null or empty database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_hr_HR.properties b/src/main/resources/messages_hr_HR.properties index f22c1272..efd24b4c 100644 --- a/src/main/resources/messages_hr_HR.properties +++ b/src/main/resources/messages_hr_HR.properties @@ -238,11 +238,13 @@ database.creationDate=Datum stvaranja database.fileSize=Veličina datoteke database.deleteBackupFile=Obriši zadao sažeto datoteke database.importBackupFile=Uvezi sažeto datoteku +database.createBackupFile=Create Backup File database.downloadBackupFile=Preuzmi sažeto datoteku database.info_1=Kada uvažavate podatke, je ključno sigurno imati ispravan struktur. Ako niste sigurni šta uradite, tražite savjet i podršku od professionala. Greška u strukturi može uzrokovati greške u aplikaciji, do i uključujući potpunu nevjerojatnost funkcionalnosti aplikacije. database.info_2=Ime datoteke nije relevantno prijevezi. Buduće bit će ponovno oznaceno za određeni format backup_user_yyyyMMddHHmm.sql, čime se osigurava konzistentna nazivnica. database.submit=Uvezi sažeto database.importIntoDatabaseSuccessed=Uvez u bazu podataka uspio +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=Datoteka ne smije biti null ili prazna database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_hu_HU.properties b/src/main/resources/messages_hu_HU.properties index 0ac19e2f..c847e646 100644 --- a/src/main/resources/messages_hu_HU.properties +++ b/src/main/resources/messages_hu_HU.properties @@ -238,11 +238,13 @@ database.creationDate=Létrehozás dátuma database.fileSize=Fájlszámítás database.deleteBackupFile=Visszaulasztó fájl törlése database.importBackupFile=Bemérsz visszaulastó fájl +database.createBackupFile=Create Backup File database.downloadBackupFile=Bemérő fájlet letöltés database.info_1=A bemeneti adatok bemérésekor fontos, hogy az helyes struktúrát biztosítsa. Ha nem tudja mit csinál, kérjen támogatást egy szakembertől. Az erőforrás hibája okozhat alkalmazás-ismerséleti gondokat, és viszontig, hogy az alkalmazás teljesen nem fut. database.info_2=A fájl neve nem jelent részt a feltöltés során. Később újra néven lesz átalakítva egy konzisztens nevésrendszert követve, a formátum: visszaulasztó_user_yyyyMMddHHmm.sql. database.submit=Bemérsz visszaulastó fájl database.importIntoDatabaseSuccessed=Adatbázisba importálva sikeresen +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=Fájlnull vagy üres nélkül nem lehet folytatni database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_id_ID.properties b/src/main/resources/messages_id_ID.properties index 4acf4dd4..d7fd7bda 100644 --- a/src/main/resources/messages_id_ID.properties +++ b/src/main/resources/messages_id_ID.properties @@ -238,11 +238,13 @@ database.creationDate=Tanggal Pembuatan database.fileSize=Ukuran Berkas database.deleteBackupFile=Hapus Berkas Cadangan database.importBackupFile=Impor Berkas Cadangan +database.createBackupFile=Create Backup File database.downloadBackupFile=Unduh Berkas Cadangan database.info_1=Ketika mengimpor data, sangat penting untuk memastikan struktur yang benar. Jika Anda tidak yakin dengan apa yang Anda lakukan, cari nasihat dan dukungan dari seorang profesional. Kesalahan dalam struktur dapat menyebabkan malfungsi aplikasi, bahkan hingga tidak dapat menjalankan aplikasi sama sekali. database.info_2=Nama berkas tidak menjadi masalah saat mengunggah. Nama berkas akan diubah setelahnya mengikuti format backup_user_yyyyMMddHHmm.sql, memastikan konsistensi dalam penamaan. database.submit=Impor Cadangan database.importIntoDatabaseSuccessed=Impor ke database berhasil +database.backupCreated=Database backup successful database.fileNotFound=Berkas tidak Ditemukan database.fileNullOrEmpty=Berkas tidak boleh null atau kosong database.failedImportFile=Impor Berkas Gagal diff --git a/src/main/resources/messages_it_IT.properties b/src/main/resources/messages_it_IT.properties index d2b422c2..e5a500b8 100644 --- a/src/main/resources/messages_it_IT.properties +++ b/src/main/resources/messages_it_IT.properties @@ -238,11 +238,13 @@ database.creationDate=Data di creazione database.fileSize=Dimensione database.deleteBackupFile=Elimina file di backup database.importBackupFile=Importa file di backup +database.createBackupFile=Crea file di backup database.downloadBackupFile=Scarica il file di backup database.info_1=Quando si importano i dati, è fondamentale garantire la struttura corretta. Se non sei sicuro di quello che stai facendo, chiedi consiglio e supporto a un professionista. Un errore nella struttura può causare malfunzionamenti dell'applicazione, fino alla completa impossibilità di eseguire l'applicazione. database.info_2=Il nome del file non ha importanza durante il caricamento. Verrà rinominato in seguito per seguire il formato backup_user__yyyyMMddHHmm.sql,garantendo una convenzione di denominazione coerente. database.submit=Importa Backup database.importIntoDatabaseSuccessed=L'importazione nel database è avvenuta con successo +database.backupCreated=Database backup successful database.fileNotFound=File non trovato database.fileNullOrEmpty=Il file non deve essere nullo o vuoto database.failedImportFile=Importazione file non riuscita diff --git a/src/main/resources/messages_ja_JP.properties b/src/main/resources/messages_ja_JP.properties index efaae957..e5bef7b4 100644 --- a/src/main/resources/messages_ja_JP.properties +++ b/src/main/resources/messages_ja_JP.properties @@ -238,11 +238,13 @@ database.creationDate=作成日 database.fileSize=ファイルサイズ database.deleteBackupFile=バックアップファイルの削除 database.importBackupFile=バックアップファイルをインポート +database.createBackupFile=Create Backup File database.downloadBackupFile=バックアップファイルをダウンロード database.info_1=データをインポートする際には、正しい構造を確保することが極めて重要です。不明な点がある場合は、専門家のアドバイスやサポートを受けてください。構造上のエラーは、アプリケーションの誤動作を引き起こす可能性があります。 database.info_2=ファイル名はアップロード時には関係ありません。アップロード後にbackup_user_yyyyMMddHHmm.sqlという形式にリネームされ、一貫した命名規則が保証されます。 database.submit=バックアップをインポート database.importIntoDatabaseSuccessed=データベースへのインポートに成功 +database.backupCreated=Database backup successful database.fileNotFound=ファイルが見つかりません database.fileNullOrEmpty=ファイルは null または空であってはなりません database.failedImportFile=ファイルのインポートに失敗 diff --git a/src/main/resources/messages_ko_KR.properties b/src/main/resources/messages_ko_KR.properties index d418fb1e..5ad547ec 100644 --- a/src/main/resources/messages_ko_KR.properties +++ b/src/main/resources/messages_ko_KR.properties @@ -238,11 +238,13 @@ database.creationDate=생성 날짜 database.fileSize=파일 크기 database.deleteBackupFile=백업 파일 삭제 database.importBackupFile=백업 파일 가져오기 +database.createBackupFile=Create Backup File database.downloadBackupFile=백업 파일 다운로드 database.info_1=데이터를 가져올 때 적절한 구조가 중요합니다. 자신이 무엇을 하는지 확실하지 않다면 전문가의 조언과 지원을 청하는 것이 좋습니다. 구조에 오류가 있으면 애플리케이션 기능 실패나 애플리케이션이 완전히 작동하지 못하게 되는 등의 문제를 초래할 수 있습니다. database.info_2=업로드 시 파일 이름은 중요하지 않습니다. 후에 backup_user_yyyyMMddHHmm.sql 형식으로 다시 지정되어 일관된 이름 규칙을 유지합니다. database.submit=백업 가져오기 database.importIntoDatabaseSuccessed=데이터베이스에 성공적으로 가져왔습니다 +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=파일은 null이나 빈 상태로 될 수 없습니다 database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_nl_NL.properties b/src/main/resources/messages_nl_NL.properties index 63425f1a..11885d9d 100644 --- a/src/main/resources/messages_nl_NL.properties +++ b/src/main/resources/messages_nl_NL.properties @@ -238,11 +238,13 @@ database.creationDate=Creatiedatum database.fileSize=Bestandsgrootte database.deleteBackupFile=Backupbestand verwijderen database.importBackupFile=Backupbestand importeren +database.createBackupFile=Create Backup File database.downloadBackupFile=Backupbestand downloaden database.info_1=Bij het importeren van gegevens is het cruciaal om de juiste structuur te zorgen voor. Als je niet zeker bent van wat je doet, raadpleeg dan advies en ondersteuning bij een professionele. Een fout in de structuur kan leiden tot toepassingsfouten, waarmee wellicht zelfs de volledige uitvoerbaarheid van de toepassing belemmerd wordt. database.info_2=De bestandsnaam maakt geen verschil bij het uploaden. Hij zal later worden herbewoond om de indeling backup_user_yyyyMMddHHmm.sql te volgen, waardoor een consistente bestandsnaamconventie waarborgd wordt. database.submit=Backup importeren database.importIntoDatabaseSuccessed=Importeer naar database succesvol +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=Bestand mag niet null of leeg zijn database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_no_NB.properties b/src/main/resources/messages_no_NB.properties index 25bd2d4a..f7e41b53 100644 --- a/src/main/resources/messages_no_NB.properties +++ b/src/main/resources/messages_no_NB.properties @@ -238,11 +238,13 @@ database.creationDate=Opprettelsesdato database.fileSize=Filstørrelse database.deleteBackupFile=Slett sikkerhetskopifil database.importBackupFile=Importer sikkerhetskopifil +database.createBackupFile=Create Backup File database.downloadBackupFile=Last ned sikkerhetskopifil database.info_1=Når du importerer data, er det avgjørende å sikre riktig struktur. Hvis du er usikker på hva du gjør, bør du søke råd og støtte fra en profesjonell. En feil i strukturen kan føre til applikasjonsfeil, inkludert fullstendig manglende evne til å kjøre applikasjonen. database.info_2=Filnavnet spiller ingen rolle ved opplasting. Det vil bli omdøpt etterpå for å følge formatet backup_user_yyyyMMddHHmm.sql, for å sikre en konsekvent navnekonvensjon. database.submit=Importer sikkerhetskopi database.importIntoDatabaseSuccessed=Import til database vellykket +database.backupCreated=Database backup successful database.fileNotFound=Fil ikke funnet database.fileNullOrEmpty=Fil må ikke være tom eller null database.failedImportFile=Import av fil mislyktes diff --git a/src/main/resources/messages_pl_PL.properties b/src/main/resources/messages_pl_PL.properties index 2e142b82..1b2f9c8e 100644 --- a/src/main/resources/messages_pl_PL.properties +++ b/src/main/resources/messages_pl_PL.properties @@ -238,11 +238,13 @@ database.creationDate=Data utworzenia database.fileSize=Rozmiar pliku database.deleteBackupFile=Usuń plik kopii zapasowej database.importBackupFile=Importuj plik kopii zapasowej +database.createBackupFile=Create Backup File database.downloadBackupFile=Pobierz plik kopii zapasowej database.info_1=Podczas importowania danych, ważne jest, aby upewnić się, że struktura jest poprawna. Jeśli nie jesteś pewien, co robisz, skontaktuj się z profesjonalistą. Błąd w strukturze może spowodować awarie aplikacji, aż do całkowitej niemożności jej uruchomienia. database.info_2=Nazwa pliku nie ma znaczenia podczas przesyłania. Zostanie on później przemianowany, aby przestrzegać formatu backup_user_yyyyMMddHHmm.sql, zapewniając spójną konwencję nazewnictwa. database.submit=Importuj kopię zapasową database.importIntoDatabaseSuccessed=Import do bazy danych zakończony sukcesem +database.backupCreated=Database backup successful database.fileNotFound=Plik nie znaleziony database.fileNullOrEmpty=Plik nie może być pusty database.failedImportFile=Nie udało się zaimportować pliku diff --git a/src/main/resources/messages_pt_BR.properties b/src/main/resources/messages_pt_BR.properties index e5431c41..f5184d4a 100644 --- a/src/main/resources/messages_pt_BR.properties +++ b/src/main/resources/messages_pt_BR.properties @@ -238,11 +238,13 @@ database.creationDate=Data de Criação database.fileSize=Tamanho do Arquivo database.deleteBackupFile=Apagar arquivo de backup database.importBackupFile=Importar arquivo de backup +database.createBackupFile=Create Backup File database.downloadBackupFile=Baixar arquivo de backup database.info_1=Ao importar dados, é crucial garantir a estrutura correta. Se você não tem certeza do que está fazendo procure auxílio de um profissional. Um erro na estrutura pode ocasionar em mau funcionamento da aplicação, incluindo a impossibilidade da aplicação ser executada. database.info_2=O nome do arquivo não importa ao enviar. Ele será renomeado em seguida para seguir o formato backup_usuario_yyyyMMddHHmm.sql, garantindo uma convenção de nomes coerente. database.submit=Importar Backup database.importIntoDatabaseSuccessed=Importação para o banco de dados bem sucedida +database.backupCreated=Database backup successful database.fileNotFound=Arquivo não encontrado database.fileNullOrEmpty=O arquivo não pode estar nulo ou vazio database.failedImportFile=Falha ao importar arquivo diff --git a/src/main/resources/messages_pt_PT.properties b/src/main/resources/messages_pt_PT.properties index f8e3a126..86457f79 100644 --- a/src/main/resources/messages_pt_PT.properties +++ b/src/main/resources/messages_pt_PT.properties @@ -238,11 +238,13 @@ database.creationDate=Data de Criação database.fileSize=Tamanho do Ficheiro database.deleteBackupFile=Apagar Ficheiro de Backup database.importBackupFile=Importar Ficheiro de Backup +database.createBackupFile=Create Backup File database.downloadBackupFile=Baixar Ficheiro de Backup database.info_1=Ao importar dados, é crucial assegurar a estrutura correta. Se não estiver seguro do que está a fazer, busque conselhos e apoio de um profissional. Um erro na estrutura pode causar mal funcionamento da aplicação, até mesmo o impossibilitar de executá-la. database.info_2=O nome do ficheiro não importa ao carregar. Será renomeado posteriormente para seguir o formato backup_user_yyyyMMddHHmm.sql, garantindo uma convenção de nomenclatura consistente. database.submit=Importar Backup database.importIntoDatabaseSuccessed=Importação no banco de dados concluída com sucesso +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=O ficheiro não pode ser nulo ou vazio database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_ro_RO.properties b/src/main/resources/messages_ro_RO.properties index e8547092..0e8b3226 100644 --- a/src/main/resources/messages_ro_RO.properties +++ b/src/main/resources/messages_ro_RO.properties @@ -238,11 +238,13 @@ database.creationDate=Data Creării database.fileSize=Dimensiune Fișier database.deleteBackupFile=Șterge Fișier de Backup database.importBackupFile=Importă Fișier de Backup +database.createBackupFile=Create Backup File database.downloadBackupFile=Descarcă Fișier de Backup database.info_1=Când importați date, este crucial să vă asigurați de structura corectă. Dacă nu sunteți sigur de ceea ce faceți, cereți sfaturi și suport de la un profesionist. O eroare în structură poate cauza defecțiuni ale aplicației, până la incapacitatea completă de a rula aplicația. database.info_2=Numele fișierului nu contează la încărcare. Va fi redenumit ulterior pentru a urma formatul backup_user_aaaallzzoomm.sql, asigurând o convenție de denumire consecventă. database.submit=Importă Backup database.importIntoDatabaseSuccessed=Importul în baza de date a reușit +database.backupCreated=Database backup successful database.fileNotFound=Fișierul nu a fost găsit database.fileNullOrEmpty=Fișierul nu trebuie să fie nul sau gol database.failedImportFile=Importul Fișierului a Eșuat diff --git a/src/main/resources/messages_ru_RU.properties b/src/main/resources/messages_ru_RU.properties index 55f20961..6bd9331d 100644 --- a/src/main/resources/messages_ru_RU.properties +++ b/src/main/resources/messages_ru_RU.properties @@ -238,11 +238,13 @@ database.creationDate=Дата создания database.fileSize=Размер файла database.deleteBackupFile=Удалить резервную копию файла database.importBackupFile=Импортировать резервную копию файла +database.createBackupFile=Create Backup File database.downloadBackupFile=Скачать резервную копию файла database.info_1=При импорте данных важно убедиться в правильной структуре. Если вы не уверены, что делаете, обратитесь за профессиональной помощью и поддержкой. Ошибка в структуре может привести к сбоям приложений, вплоть до полного их отказа от работы. database.info_2=Имя файла не имеет значения при загрузке. Оно будет переименовано позже в формат backup_user_yyyyMMddHHmm.sql для обеспечения единообразия названий. database.submit=Импортировать резервную копию database.importIntoDatabaseSuccessed=Импорт в базу данных выполнен успешно +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=Файл не должен быть пустым или NULL database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_sk_SK.properties b/src/main/resources/messages_sk_SK.properties index 4a3e09c6..66da4214 100644 --- a/src/main/resources/messages_sk_SK.properties +++ b/src/main/resources/messages_sk_SK.properties @@ -238,11 +238,13 @@ database.creationDate=Creation Date database.fileSize=File Size database.deleteBackupFile=Delete Backup File database.importBackupFile=Import Backup File +database.createBackupFile=Create Backup File database.downloadBackupFile=Download Backup File database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.submit=Import Backup database.importIntoDatabaseSuccessed=Import into database successed +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=File must not be null or empty database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_sr_LATN_RS.properties b/src/main/resources/messages_sr_LATN_RS.properties index eca99560..a6019545 100644 --- a/src/main/resources/messages_sr_LATN_RS.properties +++ b/src/main/resources/messages_sr_LATN_RS.properties @@ -238,11 +238,13 @@ database.creationDate=Creation Date database.fileSize=File Size database.deleteBackupFile=Delete Backup File database.importBackupFile=Import Backup File +database.createBackupFile=Create Backup File database.downloadBackupFile=Download Backup File database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.submit=Import Backup database.importIntoDatabaseSuccessed=Import into database successed +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=File must not be null or empty database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_sv_SE.properties b/src/main/resources/messages_sv_SE.properties index 006ef41d..ec26aaa1 100644 --- a/src/main/resources/messages_sv_SE.properties +++ b/src/main/resources/messages_sv_SE.properties @@ -238,11 +238,13 @@ database.creationDate=Skapelsedatum database.fileSize=Filstorlek database.deleteBackupFile=Ta bort säkerhetskopieringsfil database.importBackupFile=Importera säkerhetskopieringsfil +database.createBackupFile=Create Backup File database.downloadBackupFile=Ladda ner säkerhetskopieringsfil database.info_1=Vid import av data är det avgörande att säkerställa korrekt struktur. Om du är osäker på vad du gör, sök råd och stöd från en professionell. Ett fel i strukturen kan orsaka funktionsfel i applikationen, upp till och inklusive fullständig oförmåga att köra applikationen. database.info_2=Filnamnet spelar ingen roll vid uppladdning. Det kommer att döpas om efteråt för att följa formatet backup_user_yyyyMMddHHmm.sql, vilket säkerställer en konsekvent namngivningskonvention. database.submit=Importera säkerhetskopia database.importIntoDatabaseSuccessed=Import till databas lyckades +database.backupCreated=Database backup successful database.fileNotFound=Filen hittades inte database.fileNullOrEmpty=Filen får inte vara null eller tom database.failedImportFile=Misslyckades med att importera fil diff --git a/src/main/resources/messages_th_TH.properties b/src/main/resources/messages_th_TH.properties index 1d60581e..ccf3fdd5 100644 --- a/src/main/resources/messages_th_TH.properties +++ b/src/main/resources/messages_th_TH.properties @@ -238,11 +238,13 @@ database.creationDate=วันที่สร้าง database.fileSize=ขนาดไฟล์ database.deleteBackupFile=ลบไฟล์สำรอง database.importBackupFile=นำเข้าไฟล์สำรอง +database.createBackupFile=Create Backup File database.downloadBackupFile=ดาวน์โหลดไฟล์สำรอง database.info_1=เมื่อนำเข้าข้อมูล จำเป็นต้องแน่ใจว่าโครงสร้างถูกต้อง หากไม่แน่ใจว่ากำลังทำอะไรอยู่ ควรขอคำแนะนำและความช่วยเหลือจากมืออาชีพ ความผิดพลาดในโครงสร้างอาจทำให้เกิดข้อบกพร่องในการทำงานของแอปพลิเคชันจนถึงขั้นไม่สามารถรันแอปพลิเคชันได้เลย database.info_2=ชื่อไฟล์ไม่สำคัญเมื่ออัปโหลด จะถูกเปลี่ยนชื่อภายหลังให้เป็นรูปแบบ backup_user_yyyyMMddHHmm.sql เพื่อให้มีการตั้งชื่อที่สอดคล้องกัน database.submit=นำเข้าสำรอง database.importIntoDatabaseSuccessed=การนำเข้าในฐานข้อมูลสำเร็จ +database.backupCreated=Database backup successful database.fileNotFound=ไม่พบไฟล์ database.fileNullOrEmpty=ไฟล์ต้องไม่ว่างเปล่าหรือไม่มีข้อมูล database.failedImportFile=การนำเข้าไฟล์ล้มเหลว diff --git a/src/main/resources/messages_tr_TR.properties b/src/main/resources/messages_tr_TR.properties index d6c75076..5b546bc3 100644 --- a/src/main/resources/messages_tr_TR.properties +++ b/src/main/resources/messages_tr_TR.properties @@ -238,11 +238,13 @@ database.creationDate=Oluşturulma Tarihi database.fileSize=Dosya Boyutu database.deleteBackupFile=Yedekleme Dosyasını Sil database.importBackupFile=Yedekleme Dosyasını İçe Aktar +database.createBackupFile=Create Backup File database.downloadBackupFile=Yedekleme Dosyasını İndir database.info_1=Verileri içe aktarırken, yapının doğru olduğundan emin olmak çok önemlidir. Ne yaptığınızdan emin değilseniz, bir uzmandan tavsiye ve destek alın. Yapıdaki bir hata, uygulamanın tamamen çalıştırılamaması da dahil olmak üzere uygulama sorunlarına neden olabilir. database.info_2=Karşıya yüklerken dosya adı önemli değildir. Daha sonra yedekleme_kullanıcısı_yyyyAAggSdd.sql biçiminde yeniden adlandırılacak ve tutarlı bir adlandırma kuralı sağlanacaktır. database.submit=Yedeklemeyi İçe Aktar database.importIntoDatabaseSuccessed=Veri tabanına başarıyla aktarıldı +database.backupCreated=Database backup successful database.fileNotFound=Dosya bulunamadı database.fileNullOrEmpty=Dosya yok veya boş olmamalıdır database.failedImportFile=Dosya İçe Aktarılamadı diff --git a/src/main/resources/messages_uk_UA.properties b/src/main/resources/messages_uk_UA.properties index 7a96d49e..fcab3ea1 100644 --- a/src/main/resources/messages_uk_UA.properties +++ b/src/main/resources/messages_uk_UA.properties @@ -238,11 +238,13 @@ database.creationDate=Creation Date database.fileSize=File Size database.deleteBackupFile=Delete Backup File database.importBackupFile=Import Backup File +database.createBackupFile=Create Backup File database.downloadBackupFile=Download Backup File database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.submit=Import Backup database.importIntoDatabaseSuccessed=Import into database successed +database.backupCreated=Database backup successful database.fileNotFound=File not Found database.fileNullOrEmpty=File must not be null or empty database.failedImportFile=Failed Import File diff --git a/src/main/resources/messages_vi_VN.properties b/src/main/resources/messages_vi_VN.properties index 1b97853f..2200c7eb 100644 --- a/src/main/resources/messages_vi_VN.properties +++ b/src/main/resources/messages_vi_VN.properties @@ -238,11 +238,13 @@ database.creationDate=Ngày tạo database.fileSize=Kích thước tệp database.deleteBackupFile=Xóa tệp sao lưu database.importBackupFile=Nhập tệp sao lưu +database.createBackupFile=Create Backup File database.downloadBackupFile=Tải xuống tệp sao lưu database.info_1=Khi nhập dữ liệu, điều quan trọng là phải đảm bảo cấu trúc chính xác. Nếu bạn không chắc chắn về những gì bạn đang làm, hãy tìm kiếm lời khuyên và hỗ trợ từ một chuyên gia. Lỗi trong cấu trúc có thể gây ra sự cố ứng dụng, thậm chí là không thể chạy ứng dụng hoàn toàn. database.info_2=Tên tệp không quan trọng khi tải lên. Nó sẽ được đổi tên sau đó để tuân theo định dạng backup_user_yyyyMMddHHmm.sql, đảm bảo quy ước đặt tên nhất quán. database.submit=Nhập bản sao lưu database.importIntoDatabaseSuccessed=Nhập vào cơ sở dữ liệu thành công +database.backupCreated=Database backup successful database.fileNotFound=Không tìm thấy tệp database.fileNullOrEmpty=Tệp không được để trống hoặc rỗng database.failedImportFile=Không thể nhập tệp diff --git a/src/main/resources/messages_zh_CN.properties b/src/main/resources/messages_zh_CN.properties index 6f3f67da..1653fa11 100644 --- a/src/main/resources/messages_zh_CN.properties +++ b/src/main/resources/messages_zh_CN.properties @@ -238,11 +238,13 @@ database.creationDate=创建时间 database.fileSize=文件大小 database.deleteBackupFile=删除备份文件 database.importBackupFile=导入备份文件 +database.createBackupFile=Create Backup File database.downloadBackupFile=下载备份文件 database.info_1=导入数据时,确保结构正确至关重要。如果您不确定自己在做什么,请寻求专业人士的建议和支持。结构错误会导致应用程序故障,甚至完全无法运行应用程序。 database.info_2=上传文件时,文件名并不重要。上传后,文件名将重命名为 backup_user_yyyyMMddHHmm.sql,以确保命名规范的一致性。 database.submit=导入备份 database.importIntoDatabaseSuccessed=导入数据库成功 +database.backupCreated=Database backup successful database.fileNotFound=未找到文件 database.fileNullOrEmpty=文件不能为空 database.failedImportFile=导入文件失败 diff --git a/src/main/resources/messages_zh_TW.properties b/src/main/resources/messages_zh_TW.properties index 6938f683..741ec44d 100644 --- a/src/main/resources/messages_zh_TW.properties +++ b/src/main/resources/messages_zh_TW.properties @@ -238,11 +238,13 @@ database.creationDate=建立日期 database.fileSize=檔案大小 database.deleteBackupFile=刪除備份檔案 database.importBackupFile=匯入備份檔案 +database.createBackupFile=Create Backup File database.downloadBackupFile=下載備份檔案 database.info_1=在匯入資料時,確保正確的結構至關重要。如果您不確定自己在做什麼,請尋求專業人士的建議和支援。結構錯誤可能會導致應用程式故障,甚至完全無法執行應用程式。 database.info_2=上傳時檔案名稱並不重要。上傳後將重新命名為 backup_user_yyyyMMddHHmm.sql 格式,以確保命名規範一致。 database.submit=匯入備份 database.importIntoDatabaseSuccessed=成功匯入資料庫 +database.backupCreated=Database backup successful database.fileNotFound=找不到檔案 database.fileNullOrEmpty=檔案不得為空或空白 database.failedImportFile=匯入檔案失敗 diff --git a/src/main/resources/static/3rdPartyLicenses.json b/src/main/resources/static/3rdPartyLicenses.json index 682ba443..8c21c652 100644 --- a/src/main/resources/static/3rdPartyLicenses.json +++ b/src/main/resources/static/3rdPartyLicenses.json @@ -434,7 +434,7 @@ { "moduleName": "io.github.pixee:java-security-toolkit", "moduleUrl": "https://github.com/pixee/java-security-toolkit", - "moduleVersion": "1.2.0", + "moduleVersion": "1.2.1", "moduleLicense": "MIT License", "moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php" }, @@ -448,7 +448,7 @@ { "moduleName": "io.micrometer:micrometer-core", "moduleUrl": "https://github.com/micrometer-metrics/micrometer", - "moduleVersion": "1.14.1", + "moduleVersion": "1.14.2", "moduleLicense": "The Apache Software License, Version 2.0", "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" }, @@ -1441,7 +1441,7 @@ { "moduleName": "org.springframework.security:spring-security-saml2-service-provider", "moduleUrl": "https://spring.io/projects/spring-security", - "moduleVersion": "6.4.1", + "moduleVersion": "6.4.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, @@ -1539,7 +1539,7 @@ { "moduleName": "org.springframework:spring-webmvc", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.2.0", + "moduleVersion": "6.2.1", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, diff --git a/src/main/resources/static/css/dragdrop.css b/src/main/resources/static/css/dragdrop.css index 65ec786f..688cbca4 100644 --- a/src/main/resources/static/css/dragdrop.css +++ b/src/main/resources/static/css/dragdrop.css @@ -29,13 +29,9 @@ } .drag-manager_dragging { - width: 0px; - visibility: hidden; + opacity: 0.2; } -.drag-manager_draghover { - width: 375px !important; -} .drag-manager_draghover .insert-file-button-container { display: none !important; @@ -46,11 +42,11 @@ } html[dir="ltr"] .drag-manager_draghover img { - left: calc(50% + 62.5px) !important; + left: 80% !important; } html[dir="rtl"] .drag-manager_draghover img { - left: 125px; + left: 25px; } .drag-manager_dragging-container .hide-on-drag { @@ -58,14 +54,17 @@ html[dir="rtl"] .drag-manager_draghover img { } .drag-manager_endpoint { - width: 80px; - height: 100%; + width: 150px; + height: 250px; background-color: #ffffff10; transition: width 0.1s; animation: end-drop-expand 0.3s ease; display: flex; align-items: center; justify-content: center; + margin-left:16px; + border-radius: 8px; + } .drag-manager_endpoint svg { @@ -74,7 +73,8 @@ html[dir="rtl"] .drag-manager_draghover img { } .drag-manager_endpoint.drag-manager_draghover { - width: 150px !important; + width: 180px !important; + border: 2px solid darkgreen; } @keyframes end-drop-expand { @@ -85,3 +85,12 @@ html[dir="rtl"] .drag-manager_draghover img { width: 80px; } } +.moved-element img { + border: 8px solid #198754; + border-radius: 3px; + transition: border 0.5s ease-out; +} + +.moved-element.remove img{ + border: 8px solid transparent; +} diff --git a/src/main/resources/static/js/downloader.js b/src/main/resources/static/js/downloader.js index 57ae8c47..77a673c0 100644 --- a/src/main/resources/static/js/downloader.js +++ b/src/main/resources/static/js/downloader.js @@ -75,10 +75,6 @@ // Check if any PDF files are encrypted and handle decryption if necessary const decryptedFiles = await checkAndDecryptFiles(url, files); files = decryptedFiles; - // Append decrypted files to formData - decryptedFiles.forEach((file, index) => { - formData.set(`fileInput`, file); - }); } submitButton.textContent = 'Processing...'; @@ -86,7 +82,7 @@ if (remoteCall === true) { if (override === 'multi' || (!multipleInputsForSingleRequest && files.length > 1 && override !== 'single')) { - await submitMultiPdfForm(url, files); + await submitMultiPdfForm(url, files, this); } else { await handleSingleDownload(url, formData); } @@ -366,7 +362,7 @@ return {filename, blob}; } - async function submitMultiPdfForm(url, files) { + async function submitMultiPdfForm(url, files, form) { const zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4; const zipFiles = files.length > zipThreshold; let jszip = null; @@ -389,7 +385,9 @@ // Get existing form data let formData; - if (postForm) { + if (form) { + formData = new FormData(form); + } else if (postForm) { formData = new FormData($(postForm)[0]); // Convert the form to a jQuery object and get the raw DOM element } else { console.log('No form with POST method found.'); @@ -412,8 +410,9 @@ const promises = chunk.map(async (file) => { let fileFormData = new FormData(); fileFormData.append('fileInput', file); - console.log(fileFormData); - // Add other form data + for (let [key, value] of fileFormData.entries()) { + console.log(key, value); + } // Add other form data for (let pair of formData.entries()) { fileFormData.append(pair[0], pair[1]); console.log(pair[0] + ', ' + pair[1]); diff --git a/src/main/resources/static/js/draggable.js b/src/main/resources/static/js/draggable.js deleted file mode 100644 index cba6f3c0..00000000 --- a/src/main/resources/static/js/draggable.js +++ /dev/null @@ -1,36 +0,0 @@ -const draggableElement = document.querySelector('.draggable-canvas'); - -// Variables to store the current position of the draggable element -let offsetX, offsetY, isDragging = false; - -draggableElement.addEventListener('mousedown', (e) => { - // Get the offset when the mouse is clicked inside the element - offsetX = e.clientX - draggableElement.getBoundingClientRect().left; - offsetY = e.clientY - draggableElement.getBoundingClientRect().top; - - // Set isDragging to true - isDragging = true; - - // Add event listeners for mouse movement and release - document.addEventListener('mousemove', onMouseMove); - document.addEventListener('mouseup', onMouseUp); -}); - -function onMouseMove(e) { - if (isDragging) { - // Calculate the new position of the element - const left = e.clientX - offsetX; - const top = e.clientY - offsetY; - - // Move the element by setting its style - draggableElement.style.left = `${left}px`; - draggableElement.style.top = `${top}px`; - } -} - -function onMouseUp() { - // Stop dragging and remove event listeners - isDragging = false; - document.removeEventListener('mousemove', onMouseMove); - document.removeEventListener('mouseup', onMouseUp); -} diff --git a/src/main/resources/static/js/multitool/DragDropManager.js b/src/main/resources/static/js/multitool/DragDropManager.js index ce79ee14..747a7a3d 100644 --- a/src/main/resources/static/js/multitool/DragDropManager.js +++ b/src/main/resources/static/js/multitool/DragDropManager.js @@ -1,23 +1,25 @@ class DragDropManager { constructor(id, wrapperId) { this.dragContainer = document.getElementById(id); - this.pageDirection = document.documentElement.getAttribute("dir"); + this.pageDirection = document.documentElement.getAttribute('dir'); this.wrapper = document.getElementById(wrapperId); this.pageDragging = false; this.hoveredEl = undefined; this.draggedImageEl = undefined; this.draggedEl = undefined; this.selectedPageElements = []; // Store selected pages for multi-page mode + this.elementTimeouts = new Map(); // Add CSS dynamically - const styleElement = document.createElement("link"); - styleElement.rel = "stylesheet"; - styleElement.href = "css/dragdrop.css"; + const styleElement = document.createElement('link'); + styleElement.rel = 'stylesheet'; + styleElement.href = 'css/dragdrop.css'; document.head.appendChild(styleElement); // Create the endpoint element - const div = document.createElement("div"); - div.classList.add("drag-manager_endpoint"); + const div = document.createElement('div'); + div.classList.add('page-container'); + div.classList.add('drag-manager_endpoint'); div.innerHTML = ` @@ -35,59 +37,63 @@ class DragDropManager { startDraggingPage(div) { if (window.selectPage) { // Multi-page drag logic - this.selectedPageElements = window.selectedPages.map((index) => { - const pageEl = document.getElementById(`page-container-${index}`); - if (pageEl) { - pageEl.initialTransform = pageEl.style.transform || "translate(0px, 0px)"; - } - return pageEl; - }).filter(Boolean); + this.selectedPageElements = window.selectedPages + .map((index) => { + const pageEl = document.getElementById(`page-container-${index}`); + if (pageEl) { + pageEl.initialTransform = pageEl.style.transform || 'translate(0px, 0px)'; + pageEl.classList.add('drag-manager_dragging'); + } + return pageEl; + }) + .filter(Boolean); if (this.selectedPageElements.length === 0) return; this.pageDragging = true; - this.draggedImageEl = document.createElement("div"); - this.draggedImageEl.classList.add("multidrag"); + this.draggedImageEl = document.createElement('div'); + this.draggedImageEl.classList.add('multidrag'); this.draggedImageEl.textContent = `${this.selectedPageElements.length} ${window.translations.dragDropMessage}`; - this.draggedImageEl.style.visibility = "hidden"; + this.draggedImageEl.style.visibility = 'hidden'; + this.dragContainer.appendChild(this.draggedImageEl); } else { // Single-page drag logic this.pageDragging = true; this.draggedEl = div; - const img = div.querySelector("img"); - div.classList.add("drag-manager_dragging"); - - const imgEl = document.createElement("img"); - imgEl.classList.add("dragged-img"); + const img = div.querySelector('img'); + div.classList.add('drag-manager_dragging'); + div.classList.remove('moved-element', 'remove'); + const imgEl = document.createElement('img'); + imgEl.classList.add('dragged-img'); imgEl.src = img.src; - imgEl.style.visibility = "hidden"; - imgEl.style.transform = `rotate(${img.style.rotate === "" ? "0deg" : img.style.rotate}) translate(-50%, -50%)`; + imgEl.style.visibility = 'hidden'; + imgEl.style.transform = `rotate(${img.style.rotate === '' ? '0deg' : img.style.rotate}) translate(-50%, -50%)`; this.draggedImageEl = imgEl; this.dragContainer.appendChild(imgEl); } // Common setup for both modes - window.addEventListener("mouseup", this.stopDraggingPage); - window.addEventListener("mousemove", this.onDragEl); - this.wrapper.classList.add("drag-manager_dragging-container"); + window.addEventListener('mouseup', this.stopDraggingPage); + window.addEventListener('mousemove', this.onDragEl); + this.wrapper.classList.add('drag-manager_dragging-container'); this.wrapper.appendChild(this.endInsertionElement); } onDragEl(mouseEvent) { - const { clientX, clientY } = mouseEvent; + const {clientX, clientY} = mouseEvent; if (this.draggedImageEl) { - this.draggedImageEl.style.visibility = "visible"; + this.draggedImageEl.style.visibility = 'visible'; this.draggedImageEl.style.left = `${clientX}px`; this.draggedImageEl.style.top = `${clientY}px`; } } stopDraggingPage() { - window.removeEventListener("mousemove", this.onDragEl); - this.wrapper.classList.remove("drag-manager_dragging-container"); + window.removeEventListener('mousemove', this.onDragEl); + this.wrapper.classList.remove('drag-manager_dragging-container'); this.wrapper.removeChild(this.endInsertionElement); - window.removeEventListener("mouseup", this.stopDraggingPage); + window.removeEventListener('mouseup', this.stopDraggingPage); if (this.draggedImageEl) { this.dragContainer.removeChild(this.draggedImageEl); @@ -96,38 +102,79 @@ class DragDropManager { if (window.selectPage) { // Multi-page drop logic - if (!this.hoveredEl) { + if ( + !this.hoveredEl || + !this.hoveredEl.classList.contains('page-container') || + this.selectedPageElements.includes(this.hoveredEl) + ) { this.selectedPageElements.forEach((pageEl) => { - pageEl.style.transform = pageEl.initialTransform || "translate(0px, 0px)"; - pageEl.classList.remove("drag-manager_dragging"); + pageEl.style.transform = pageEl.initialTransform || 'translate(0px, 0px)'; + pageEl.classList.remove('drag-manager_dragging'); }); } else { this.selectedPageElements.forEach((pageEl) => { - pageEl.classList.remove("drag-manager_dragging"); + pageEl.classList.remove('drag-manager_dragging'); + if (this.hoveredEl === this.endInsertionElement) { this.movePageTo(pageEl); } else { this.movePageTo(pageEl, this.hoveredEl); } + + // Handle timeout for the current element + this.handleTimeoutForElement(pageEl); }); } this.selectedPageElements = []; - window.resetPages() + window.resetPages(); } else { // Single-page drop logic - if (!this.hoveredEl) return; - this.draggedEl.classList.remove("drag-manager_dragging"); + if ( + !this.hoveredEl || + !this.hoveredEl.classList.contains('page-container') || + this.hoveredEl === this.draggedEl + ) { + this.draggedEl.style.transform = this.draggedEl.initialTransform || 'translate(0px, 0px)'; + this.draggedEl.classList.remove('drag-manager_dragging'); + return; + } + + this.draggedEl.classList.remove('drag-manager_dragging'); + if (this.hoveredEl === this.endInsertionElement) { this.movePageTo(this.draggedEl); } else { this.movePageTo(this.draggedEl, this.hoveredEl); } + + // Handle timeout for the current element + this.handleTimeoutForElement(this.draggedEl); } this.pageDragging = false; } - setActions({ movePageTo }) { + // Helper function to manage independent timeouts + handleTimeoutForElement(element) { + // Clear existing timeout if present + if (this.elementTimeouts.has(element)) { + clearTimeout(this.elementTimeouts.get(element)); + } + + // Add the moved-element class and set a new timeout + element.classList.remove('remove'); + element.classList.add('moved-element'); + + const timeoutId = setTimeout(() => { + element.classList.add('remove'); + this.elementTimeouts.delete(element); // Cleanup the timeout map + }, 2000); + + // Store the timeout ID for this element + this.elementTimeouts.set(element, timeoutId); + } + + setActions({movePageTo}) { this.movePageTo = movePageTo; } @@ -140,18 +187,18 @@ class DragDropManager { const onMouseEnter = () => { if (this.pageDragging) { this.hoveredEl = div; - div.classList.add("drag-manager_draghover"); + div.classList.add('drag-manager_draghover'); } }; const onMouseLeave = () => { this.hoveredEl = undefined; - div.classList.remove("drag-manager_draghover"); + div.classList.remove('drag-manager_draghover'); }; - div.addEventListener("dragstart", onDragStart); - div.addEventListener("mouseenter", onMouseEnter); - div.addEventListener("mouseleave", onMouseLeave); + div.addEventListener('dragstart', onDragStart); + div.addEventListener('mouseenter', onMouseEnter); + div.addEventListener('mouseleave', onMouseLeave); return div; } diff --git a/src/main/resources/static/js/multitool/commands/move-page.js b/src/main/resources/static/js/multitool/commands/move-page.js index 6f7b185e..738af950 100644 --- a/src/main/resources/static/js/multitool/commands/move-page.js +++ b/src/main/resources/static/js/multitool/commands/move-page.js @@ -1,13 +1,7 @@ -import { Command } from "./command.js"; +import {Command} from './command.js'; export class AbstractMovePageCommand extends Command { - constructor( - startElement, - endElement, - pagesContainer, - pagesContainerWrapper, - scrollTo = false - ) { + constructor(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo = false) { super(); this.pagesContainer = pagesContainer; @@ -25,7 +19,7 @@ export class AbstractMovePageCommand extends Command { execute() { // Check & remove page number elements here too if they exist because Firefox doesn't fire the relevant event on page move. - const pageNumberElement = this.startElement.querySelector(".page-number"); + const pageNumberElement = this.startElement.querySelector('.page-number'); if (pageNumberElement) { this.startElement.removeChild(pageNumberElement); } @@ -38,11 +32,8 @@ export class AbstractMovePageCommand extends Command { } if (this.scrollTo) { - const { width } = this.startElement.getBoundingClientRect(); - const vector = - this.endIndex !== -1 && this.startIndex > this.endIndex - ? 0 - width - : width; + const {width} = this.startElement.getBoundingClientRect(); + const vector = this.endIndex !== -1 && this.startIndex > this.endIndex ? 0 - width : width; this.pagesContainerWrapper.scroll({ left: this.pagesContainerWrapper.scrollLeft + vector, @@ -52,7 +43,6 @@ export class AbstractMovePageCommand extends Command { undo() { // Requires overriding in child classes - } redo() { @@ -61,28 +51,19 @@ export class AbstractMovePageCommand extends Command { } export class MovePageUpCommand extends AbstractMovePageCommand { - constructor( - startElement, - endElement, - pagesContainer, - pagesContainerWrapper, - scrollTo = false - ) { + constructor(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo = false) { super(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo); } undo() { if (this.endElement) { this.pagesContainer.removeChild(this.endElement); - this.startElement.insertAdjacentElement("beforebegin", this.endElement); + this.startElement.insertAdjacentElement('beforebegin', this.endElement); } if (this.scrollTo) { - const { width } = this.startElement.getBoundingClientRect(); - const vector = - this.endIndex === -1 || this.startIndex <= this.endIndex - ? 0 - width - : width; + const {width} = this.startElement.getBoundingClientRect(); + const vector = this.endIndex === -1 || this.startIndex <= this.endIndex ? 0 - width : width; this.pagesContainerWrapper.scroll({ left: this.pagesContainerWrapper.scrollLeft - vector, @@ -96,13 +77,7 @@ export class MovePageUpCommand extends AbstractMovePageCommand { } export class MovePageDownCommand extends AbstractMovePageCommand { - constructor( - startElement, - endElement, - pagesContainer, - pagesContainerWrapper, - scrollTo = false - ) { + constructor(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo = false) { super(startElement, endElement, pagesContainer, pagesContainerWrapper, scrollTo); } @@ -111,15 +86,12 @@ export class MovePageDownCommand extends AbstractMovePageCommand { if (this.startElement) { this.pagesContainer.removeChild(this.startElement); - previousElement.insertAdjacentElement("beforebegin", this.startElement); + previousElement.insertAdjacentElement('beforebegin', this.startElement); } if (this.scrollTo) { - const { width } = this.startElement.getBoundingClientRect(); - const vector = - this.endIndex === -1 || this.startIndex <= this.endIndex - ? 0 - width - : width; + const {width} = this.startElement.getBoundingClientRect(); + const vector = this.endIndex === -1 || this.startIndex <= this.endIndex ? 0 - width : width; this.pagesContainerWrapper.scroll({ left: this.pagesContainerWrapper.scrollLeft - vector, diff --git a/src/main/resources/static/js/pages/adjust-contrast.js b/src/main/resources/static/js/pages/adjust-contrast.js index 792c0666..a9692d2b 100644 --- a/src/main/resources/static/js/pages/adjust-contrast.js +++ b/src/main/resources/static/js/pages/adjust-contrast.js @@ -222,7 +222,7 @@ async function downloadPDF() { // Event listeners document.getElementById('fileInput-input').addEventListener('change', function (e) { - const fileInput = event.target; + const fileInput = e.target; fileInput.addEventListener('file-input-change', async (e) => { const {allFiles} = e.detail; if (allFiles && allFiles.length > 0) { diff --git a/src/main/resources/templates/convert/img-to-pdf.html b/src/main/resources/templates/convert/img-to-pdf.html index 758e8328..fa0fc74f 100644 --- a/src/main/resources/templates/convert/img-to-pdf.html +++ b/src/main/resources/templates/convert/img-to-pdf.html @@ -17,7 +17,7 @@ image -
+
@@ -51,15 +51,18 @@
diff --git a/src/main/resources/templates/database.html b/src/main/resources/templates/database.html index 1a86a4fc..dd36bac4 100644 --- a/src/main/resources/templates/database.html +++ b/src/main/resources/templates/database.html @@ -42,6 +42,7 @@
DB-Version
+ Create Backup File
diff --git a/src/main/resources/templates/merge-pdfs.html b/src/main/resources/templates/merge-pdfs.html index f6ace6d7..1670a446 100644 --- a/src/main/resources/templates/merge-pdfs.html +++ b/src/main/resources/templates/merge-pdfs.html @@ -5,6 +5,7 @@ + diff --git a/src/main/resources/templates/sign.html b/src/main/resources/templates/sign.html index a0fe2f10..88281338 100644 --- a/src/main/resources/templates/sign.html +++ b/src/main/resources/templates/sign.html @@ -236,9 +236,6 @@ - - - \ No newline at end of file