diff --git a/Dockerfile b/Dockerfile index f0eb592c..63bbc6b0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,37 +11,30 @@ ENV DOCKER_ENABLE_SECURITY=false \ # PUID=1000 \ # PGID=1000 \ # UMASK=022 \ - + +# Copy necessary files +COPY scripts /scripts +COPY pipeline /pipeline +COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto +COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto +COPY build/libs/*.jar app.jar # Create user and group ##RUN groupadd -g $PGID stirlingpdfgroup && \ ## useradd -u $PUID -g stirlingpdfgroup -s /bin/sh stirlingpdfuser && \ -## mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME - +## mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME && \ # Set up necessary directories and permissions -RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /logs /customFiles /pipeline /pipeline/defaultWebUIConfigs /pipeline/watchedFolders /pipeline/finishedFolders +RUN mkdir /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \ ##&& \ ## chown -R stirlingpdfuser:stirlingpdfgroup /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /customFiles && \ -## chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/tesseract-ocr-original - -# Copy necessary files -COPY ./scripts/* /scripts/ -COPY ./pipeline/ /pipeline/ -COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/ -COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto/ -COPY build/libs/*.jar app.jar - +## chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/tesseract-ocr-original && \ # Set font cache and permissions -RUN fc-cache -f -v && chmod +x /scripts/* - -##&& \ + fc-cache -f -v && \ + chmod +x /scripts/* ## chown stirlingpdfuser:stirlingpdfgroup /app.jar && \ ## chmod +x /scripts/init.sh -# Expose necessary ports -EXPOSE 8080 - # Set user and run command ##USER stirlingpdfuser -ENTRYPOINT ["/scripts/init.sh"] +ENTRYPOINT ["tini", "--", "/scripts/init.sh"] CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"] diff --git a/Dockerfile-lite b/Dockerfile-lite index 054c7639..979d97de 100644 --- a/Dockerfile-lite +++ b/Dockerfile-lite @@ -1,65 +1,60 @@ -# Build jbig2enc in a separate stage -FROM bellsoft/liberica-openjdk-debian:17 +# use alpine +FROM alpine:3.19.0 ARG VERSION_TAG -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - libreoffice-core \ - libreoffice-common \ - libreoffice-writer \ - libreoffice-calc \ - libreoffice-impress \ - unoconv && \ - rm -rf /var/lib/apt/lists/* - - # Set Environment Variables ENV DOCKER_ENABLE_SECURITY=false \ HOME=/home/stirlingpdfuser \ VERSION_TAG=$VERSION_TAG \ JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" -# PUID=1000 \ +# PUID=1000 \ # PGID=1000 \ # UMASK=022 \ +# Copy necessary files +COPY scripts/download-security-jar.sh /scripts/download-security-jar.sh +COPY scripts/init-without-ocr.sh /scripts/init-without-ocr.sh +COPY pipeline /pipeline +COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto +COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto +COPY build/libs/*.jar app.jar + +RUN apk add --no-cache \ + ca-certificates \ + tzdata \ + tini \ + bash \ + curl \ + openjdk17-jre && \ +# Doc conversion + apk add --no-cache libreoffice --repository http://dl-cdn.alpinelinux.org/alpine/edge/community && \ +# python and pip + apk add --no-cache \ + python3 && \ + wget https://bootstrap.pypa.io/get-pip.py -qO - | python3 - --break-system-packages --no-cache-dir --upgrade && \ +# uno unoconv and HTML + pip install --break-system-packages --no-cache-dir --upgrade unoconv WeasyPrint && \ # Create user and group #RUN groupadd -g $PGID stirlingpdfgroup && \ # useradd -u $PUID -g stirlingpdfgroup -s /bin/sh stirlingpdfuser && \ # mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME - # Set up necessary directories and permissions -RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /configs /customFiles /logs /pipeline /pipeline/defaultWebUIConfigs /pipeline/watchedFolders /pipeline/finishedFolders - + mkdir /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \ # chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/fonts/opentype/noto /configs /customFiles - -# Copy necessary files -COPY ./scripts/download-security-jar.sh /scripts/download-security-jar.sh -COPY ./scripts/init-without-ocr.sh /scripts/init-without-ocr.sh -COPY ./pipeline/ /pipeline/ -COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/ -COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto/ -COPY build/libs/*.jar app.jar - # Set font cache and permissions -RUN fc-cache -f -v && \ -chmod +x /scripts/init-without-ocr.sh && \ -chmod +x /scripts/download-security-jar.sh - - + fc-cache -f -v && \ + chmod +x /scripts/*.sh && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories # chown stirlingpdfuser:stirlingpdfgroup /app.jar - - - -# Expose the application port -EXPOSE 8080 - # Set environment variables -ENV ENDPOINTS_GROUPS_TO_REMOVE=Python,OpenCV,OCRmyPDF +ENV ENDPOINTS_GROUPS_TO_REMOVE=OpenCV,OCRmyPDF ENV DOCKER_ENABLE_SECURITY=false # Run the application #USER stirlingpdfuser -ENTRYPOINT ["/scripts/init-without-ocr.sh"] +ENTRYPOINT ["tini", "--", "/scripts/init-without-ocr.sh"] CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"] diff --git a/Dockerfile-ultra-lite b/Dockerfile-ultra-lite index d77c1b94..e01debb0 100644 --- a/Dockerfile-ultra-lite +++ b/Dockerfile-ultra-lite @@ -1,5 +1,5 @@ -# Build jbig2enc in a separate stage -FROM bellsoft/liberica-openjdk-alpine:17 +# use alpine +FROM alpine:3.19.0 ARG VERSION_TAG @@ -8,39 +8,42 @@ ENV DOCKER_ENABLE_SECURITY=false \ HOME=/home/stirlingpdfuser \ VERSION_TAG=$VERSION_TAG \ JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" -# PUID=1000 \ +# PUID=1000 \ # PGID=1000 \ # UMASK=022 \ +# Copy necessary files +COPY scripts/download-security-jar.sh /scripts/download-security-jar.sh +COPY scripts/init-without-ocr.sh /scripts/init-without-ocr.sh +COPY pipeline /pipeline +COPY build/libs/*.jar app.jar + # Create user and group using Alpine's addgroup and adduser #RUN addgroup -g $PGID stirlingpdfgroup && \ # adduser -u $PUID -G stirlingpdfgroup -s /bin/sh -D stirlingpdfuser && \ # mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME - # Set up necessary directories and permissions #RUN mkdir -p /scripts /configs /customFiles && \ -# chown -R stirlingpdfuser:stirlingpdfgroup /scripts /configs /customFiles /logs /pipeline /pipeline/defaultWebUIConfigs /pipeline/watchedFolders /pipeline/finishedFolders - -RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /configs /customFiles -COPY ./scripts/download-security-jar.sh /scripts/download-security-jar.sh -COPY ./scripts/init-without-ocr.sh /scripts/init-without-ocr.sh -COPY ./pipeline/ /pipeline/ -COPY build/libs/*.jar app.jar - +# chown -R stirlingpdfuser:stirlingpdfgroup /scripts /configs /customFiles /logs /pipeline /pipeline/defaultWebUIConfigs /pipeline/watchedFolders /pipeline/finishedFolders +RUN mkdir /configs /logs /customFiles && \ # Set font cache and permissions #RUN chown stirlingpdfuser:stirlingpdfgroup /app.jar - -RUN chmod +x /scripts/init-without-ocr.sh && \ -chmod +x /scripts/download-security-jar.sh && \ -apk add --no-cache curl - -# Expose the application port -EXPOSE 8080 + chmod +x /scripts/*.sh && \ + apk add --no-cache \ + ca-certificates \ + tzdata \ + tini \ + bash \ + curl \ + openjdk17-jre && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories # Set environment variables ENV ENDPOINTS_GROUPS_TO_REMOVE=CLI -ENTRYPOINT ["/scripts/init-without-ocr.sh"] +ENTRYPOINT ["tini", "--", "/scripts/init-without-ocr.sh"] # Run the application CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"] diff --git a/DockerfileBase b/DockerfileBase index b37050c7..44e1a582 100644 --- a/DockerfileBase +++ b/DockerfileBase @@ -1,43 +1,28 @@ # Main stage -FROM ubuntu:latest AS base - - +FROM alpine:3.19.0 # JDK for app -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - openjdk-17-jre && \ - rm -rf /var/lib/apt/lists/* - +RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \ + echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \ + apk add --no-cache \ + ca-certificates \ + tzdata \ + tini \ + bash \ + curl \ + openjdk17-jre \ # Doc conversion -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - libreoffice-core \ - libreoffice-common \ - libreoffice-writer \ - libreoffice-calc \ - libreoffice-impress \ - python3-uno \ - curl \ - unoconv && \ - rm -rf /var/lib/apt/lists/* - - + libreoffice@testing \ # OCR MY PDF (unpaper for descew and other advanced featues) -RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common gnupg2 && \ -add-apt-repository ppa:alex-p/tesseract-ocr5 && apt install -y --no-install-recommends tesseract-ocr && \ -apt-get update && \ - apt-get install -y --no-install-recommends \ - ghostscript \ - python3-pip \ ocrmypdf \ - unpaper && \ - rm -rf /var/lib/apt/lists/* && \ - mv /usr/share/tesseract-ocr /usr/share/tesseract-ocr-original && \ - pip install --no-cache-dir --upgrade pip && \ - pip install --no-cache-dir --upgrade ocrmypdf && \ - pip install --no-cache-dir --upgrade pillow==10.0.1 reportlab==3.6.13 wheel==0.38.1 setuptools==65.5.1 pyjwt==2.4.0 cryptography==39.0.1 - - -#CV and HTML -RUN pip install --no-cache-dir opencv-python-headless WeasyPrint + tesseract-ocr-data-eng \ +# CV + py3-opencv \ +# python3/pip + python3 && \ + wget https://bootstrap.pypa.io/get-pip.py -qO - | python3 - --break-system-packages --no-cache-dir --upgrade && \ +# uno unoconv and HTML + pip install --break-system-packages --no-cache-dir --upgrade unoconv WeasyPrint && \ + mv /usr/share/tessdata /usr/share/tessdata-original + diff --git a/HowToUseOCR.md b/HowToUseOCR.md index d83d0fd2..8fdf8fe4 100644 --- a/HowToUseOCR.md +++ b/HowToUseOCR.md @@ -21,7 +21,7 @@ Depending on your requirements, you can choose the appropriate language pack for ### Installing Language Packs 1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need. -2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tesseract-ocr/5/tessdata` (Debian) or `/usr/share/tesseract/tessdata` (Fedora) +2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tessdata` # DO NOT REMOVE EXISTING ENG.TRAINEDDATA, IT'S REQUIRED. @@ -37,14 +37,14 @@ services: your_service_name: image: your_docker_image_name volumes: - - /location/of/trainingData:/usr/share/tesseract-ocr/5/tessdata + - /location/of/trainingData:/usr/share/tessdata ``` #### Docker run Add the following to your existing docker run command ```bash --v /location/of/trainingData:/usr/share/tesseract-ocr/5/tessdata +-v /location/of/trainingData:/usr/share/tessdata ``` #### Non-Docker diff --git a/LocalRunGuide.md b/LocalRunGuide.md index 824c1ae7..75a53b80 100644 --- a/LocalRunGuide.md +++ b/LocalRunGuide.md @@ -139,7 +139,7 @@ Easiest is to use the langpacks provided by your repositories. Skip the other st Manual: 1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need. -2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tesseract-ocr/5/tessdata` +2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tessdata` 3. Please view [OCRmyPDF install guide](https://ocrmypdf.readthedocs.io/en/latest/installation.html) for more info. **IMPORTANT:** DO NOT REMOVE EXISTING `eng.traineddata`, IT'S REQUIRED. diff --git a/README.md b/README.md index e8814b80..5876a7e2 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ Docker Run ```bash docker run -d \ -p 8080:8080 \ - -v /location/of/trainingData:/usr/share/tesseract-ocr/5/tessdata \ + -v /location/of/trainingData:/usr/share/tessdata \ -v /location/of/extraConfigs:/configs \ -v /location/of/logs:/logs \ -e DOCKER_ENABLE_SECURITY=false \ @@ -131,7 +131,7 @@ services: ports: - '8080:8080' volumes: - - /location/of/trainingData:/usr/share/tesseract-ocr/5/tessdata #Required for extra OCR languages + - /location/of/trainingData:/usr/share/tessdata #Required for extra OCR languages - /location/of/extraConfigs:/configs # - /location/of/customFiles:/customFiles/ # - /location/of/logs:/logs/ diff --git a/build.gradle b/build.gradle index 7025b2bd..2e8bbbdf 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { import com.github.jk1.license.render.* group = 'stirling.software' -version = '0.20.2' +version = '0.21.0' sourceCompatibility = '17' repositories { diff --git a/scripts/init.sh b/scripts/init.sh index 8f1f96db..ea8fd359 100644 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -2,11 +2,15 @@ # Copy the original tesseract-ocr files to the volume directory without overwriting existing files echo "Copying original files without overwriting existing files" -mkdir -p /usr/share/tesseract-ocr -cp -rn /usr/share/tesseract-ocr-original/* /usr/share/tesseract-ocr +mkdir -p /usr/share/tessdata +cp -rn /usr/share/tessdata-original/* /usr/share/tessdata -if [ -d /usr/share/tesseract-ocr/4.00/tessdata ]; then - cp -r /usr/share/tesseract-ocr/4.00/tessdata/* /usr/share/tesseract-ocr/5/tessdata/ || true; +if [ -d /usr/share/tesseract-ocr/4.00/tessdata ]; then + cp -r /usr/share/tesseract-ocr/4.00/tessdata/* /usr/share/tessdata || true; +fi + +if [ -d /usr/share/tesseract-ocr/5/tessdata ]; then + cp -r /usr/share/tesseract-ocr/5/tessdata/* /usr/share/tessdata || true; fi # Check if TESSERACT_LANGS environment variable is set and is not empty @@ -23,4 +27,4 @@ fi /scripts/download-security-jar.sh # Run the main command -exec "$@" \ No newline at end of file +exec "$@" 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 6accfb7a..e1355c30 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 @@ -68,7 +68,7 @@ public class ShowJavascript { if (script.isEmpty()) { script = - "PDF '" + inputFile.getOriginalFilename() + "' does not contain Javascript"; + "PDF '" + Filenames.toSimpleFileName(inputFile.getOriginalFilename()) + "' does not contain Javascript"; } return WebResponseUtils.bytesToWebResponse( diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/StampController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/StampController.java index 4779b077..cfde30c1 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/StampController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/StampController.java @@ -53,7 +53,6 @@ public class StampController { public ResponseEntity addStamp(@ModelAttribute AddStampRequest request) throws IOException, Exception { MultipartFile pdfFile = request.getFileInput(); - List pageNumbers = request.getPageNumbersList(); String watermarkType = request.getStampType(); String watermarkText = request.getStampText(); MultipartFile watermarkImage = request.getStampImage(); @@ -67,6 +66,7 @@ public class StampController { String customColor = request.getCustomColor(); float marginFactor; + switch (request.getCustomMargin().toLowerCase()) { case "small": marginFactor = 0.02f; @@ -80,7 +80,6 @@ public class StampController { case "x-large": marginFactor = 0.075f; break; - default: marginFactor = 0.035f; break; @@ -89,58 +88,61 @@ public class StampController { // Load the input PDF PDDocument document = Loader.loadPDF(pdfFile.getBytes()); + List pageNumbers = request.getPageNumbersList(); + for (int pageIndex : pageNumbers) { - // Convert 1-based index to 0-based index required by - // document.getPages().get(index) int zeroBasedIndex = pageIndex - 1; - // Check if the zeroBasedIndex is within the range of the document's pages if (zeroBasedIndex >= 0 && zeroBasedIndex < document.getNumberOfPages()) { PDPage page = document.getPage(zeroBasedIndex); + PDRectangle pageSize = page.getMediaBox(); + float margin = marginFactor * (pageSize.getWidth() + pageSize.getHeight()) / 2; + + PDPageContentStream contentStream = new PDPageContentStream( document, page, PDPageContentStream.AppendMode.APPEND, true, true); - PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState(); - graphicsState.setNonStrokingAlphaConstant(opacity); - contentStream.setGraphicsStateParameters(graphicsState); - if ("text".equalsIgnoreCase(watermarkType)) { - addTextStamp( - contentStream, - watermarkText, - document, - page, - rotation, - position, - fontSize, - alphabet, - overrideX, - overrideY, - marginFactor, - customColor); - } else if ("image".equalsIgnoreCase(watermarkType)) { - addImageStamp( - contentStream, - watermarkImage, - document, - page, - rotation, - position, - fontSize, - overrideX, - overrideY, - marginFactor); - } - - contentStream.close(); - } + PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState(); + graphicsState.setNonStrokingAlphaConstant(opacity); + contentStream.setGraphicsStateParameters(graphicsState); + + if ("text".equalsIgnoreCase(watermarkType)) { + addTextStamp( + contentStream, + watermarkText, + document, + page, + rotation, + position, + fontSize, + alphabet, + overrideX, + overrideY, + margin, + customColor); + } else if ("image".equalsIgnoreCase(watermarkType)) { + addImageStamp( + contentStream, + watermarkImage, + document, + page, + rotation, + position, + fontSize, + overrideX, + overrideY, + margin); + } + + contentStream.close(); + } } - return WebResponseUtils.pdfDocToWebResponse( document, Filenames.toSimpleFileName(pdfFile.getOriginalFilename()) .replaceFirst("[.][^.]+$", "") - + "_stamped.pdf"); + + "_watermarked.pdf"); } private void addTextStamp( @@ -154,7 +156,7 @@ public class StampController { String alphabet, float overrideX, // X override float overrideY, - float marginFactor, + float margin, String colorString) // Y override throws IOException { String resourceDir = ""; @@ -216,14 +218,10 @@ public class StampController { } else { x = calculatePositionX( - pageSize, - position, - fontSize, - font, - fontSize, - watermarkText, - marginFactor); - y = calculatePositionY(pageSize, position, fontSize, marginFactor); + pageSize, position, fontSize, font, fontSize, watermarkText, margin); + y = + calculatePositionY( + pageSize, position, calculateTextCapHeight(font, fontSize), margin); } contentStream.beginText(); @@ -242,7 +240,7 @@ public class StampController { float fontSize, float overrideX, float overrideY, - float marginFactor) + float margin) throws IOException { // Load the watermark image @@ -268,10 +266,8 @@ public class StampController { x = overrideX; y = overrideY; } else { - x = - calculatePositionX( - pageSize, position, desiredPhysicalWidth, null, 0, null, marginFactor); - y = calculatePositionY(pageSize, position, fontSize, marginFactor); + x = calculatePositionX(pageSize, position, desiredPhysicalWidth, null, 0, null, margin); + y = calculatePositionY(pageSize, position, fontSize, margin); } contentStream.saveGraphicsState(); @@ -288,17 +284,31 @@ public class StampController { PDFont font, float fontSize, String text, - float marginFactor) + float margin) throws IOException { float actualWidth = (text != null) ? calculateTextWidth(text, font, fontSize) : contentWidth; switch (position % 3) { case 1: // Left - return pageSize.getLowerLeftX() + marginFactor * pageSize.getWidth(); + return pageSize.getLowerLeftX() + margin; case 2: // Center return (pageSize.getWidth() - actualWidth) / 2; case 0: // Right - return pageSize.getUpperRightX() - actualWidth - marginFactor * pageSize.getWidth(); + return pageSize.getUpperRightX() - actualWidth - margin; + default: + return 0; + } + } + + private float calculatePositionY( + PDRectangle pageSize, int position, float height, float margin) { + switch ((position - 1) / 3) { + case 0: // Top + return pageSize.getUpperRightY() - height - margin; + case 1: // Middle + return (pageSize.getHeight() - height) / 2; + case 2: // Bottom + return pageSize.getLowerLeftY() + margin; default: return 0; } @@ -308,17 +318,7 @@ public class StampController { return font.getStringWidth(text) / 1000 * fontSize; } - private float calculatePositionY( - PDRectangle pageSize, int position, float height, float marginFactor) { - switch ((position - 1) / 3) { - case 0: // Top - return pageSize.getUpperRightY() - height - marginFactor * pageSize.getHeight(); - case 1: // Middle - return (pageSize.getHeight() - height) / 2; - case 2: // Bottom - return pageSize.getLowerLeftY() + marginFactor * pageSize.getHeight(); - default: - return 0; - } + private float calculateTextCapHeight(PDFont font, float fontSize) { + return font.getFontDescriptor().getCapHeight() / 1000 * fontSize; } } diff --git a/src/main/resources/messages_es_ES.properties b/src/main/resources/messages_es_ES.properties index 538cc776..37bc5a06 100644 --- a/src/main/resources/messages_es_ES.properties +++ b/src/main/resources/messages_es_ES.properties @@ -42,9 +42,9 @@ red=Rojo green=Verde blue=Azul custom=Personalizado... -WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems! -poweredBy=Powered by -yes=Yes +WorkInProgess=Tarea en progreso, puede no funcionar o ralentizarse; ¡por favor, informe de cualquier problema! +poweredBy=Desarrollado por +yes=Sí no=No changedCredsMessage=Se cambiaron las credenciales! notAuthenticatedMessage=Usuario no autentificado. @@ -56,24 +56,24 @@ usernameExistsMessage=El nuevo nombre de usuario está en uso. ############### # Pipeline # ############### -pipeline.header=Pipeline Menu (Alpha) -pipeline.uploadButton=Upload Custom -pipeline.configureButton=Configure -pipeline.defaultOption=Custom -pipeline.submitButton=Submit +pipeline.header=Menu Pipeline (Alfa) +pipeline.uploadButton=Cargar personalización +pipeline.configureButton=Configurar +pipeline.defaultOption=Personalizar +pipeline.submitButton=Enviar ###################### # Pipeline Options # ###################### -pipelineOptions.header=Pipeline Configuration -pipelineOptions.pipelineNameLabel=Pipeline Name -pipelineOptions.saveSettings=Save Operation Settings -pipelineOptions.pipelineNamePrompt=Enter pipeline name here -pipelineOptions.selectOperation=Select Operation -pipelineOptions.addOperationButton=Add operation +pipelineOptions.header=Configuración Pipeline +pipelineOptions.pipelineNameLabel=Nombre del Pipeline +pipelineOptions.saveSettings=Guardar configuración de la oiperación +pipelineOptions.pipelineNamePrompt=Introduzca aquí el nombre del pipeline +pipelineOptions.selectOperation=Seleccione la operación +pipelineOptions.addOperationButton=Añadir operación pipelineOptions.pipelineHeader=Pipeline: -pipelineOptions.saveButton=Download -pipelineOptions.validateButton=Validate +pipelineOptions.saveButton=Descargar +pipelineOptions.validateButton=Validar @@ -466,37 +466,37 @@ HTMLToPDF.header=HTML a PDF HTMLToPDF.help=Acepta archivos HTML y ZIPs conteniendo los html/css/imágenes, etc, requeridas HTMLToPDF.submit=Convertir HTMLToPDF.credit=Utiliza WeasyPrint -HTMLToPDF.zoom=Zoom level for displaying the website. -HTMLToPDF.pageWidth=Width of the page in centimeters. (Blank to default) -HTMLToPDF.pageHeight=Height of the page in centimeters. (Blank to default) -HTMLToPDF.marginTop=Top margin of the page in millimeters. (Blank to default) -HTMLToPDF.marginBottom=Bottom margin of the page in millimeters. (Blank to default) -HTMLToPDF.marginLeft=Left margin of the page in millimeters. (Blank to default) -HTMLToPDF.marginRight=Right margin of the page in millimeters. (Blank to default) -HTMLToPDF.printBackground=Render the background of websites. -HTMLToPDF.defaultHeader=Enable Default Header (Name and page number) -HTMLToPDF.cssMediaType=Change the CSS media type of the page. -HTMLToPDF.none=None -HTMLToPDF.print=Print -HTMLToPDF.screen=Screen +HTMLToPDF.zoom=Nivel de zoom para mostrar la página web. +HTMLToPDF.pageWidth=Ancho de la página en centímetros. (Dejar en blanco por defecto) +HTMLToPDF.pageHeight=Alto de la página en centímetros. (Dejar en blanco por defecto) +HTMLToPDF.marginTop=Margen superior de la página en milímetros. (Dejar en blanco por defecto) +HTMLToPDF.marginBottom=Margen inferior de la página en milímetros. (Dejar en blanco por defecto) +HTMLToPDF.marginLeft=Margen izquierdo de la página en milímetros. (Dejar en blanco por defecto) +HTMLToPDF.marginRight=Margen derecho de la página en milímetros. (Dejar en blanco por defecto) +HTMLToPDF.printBackground=Renderizar el fondo de las páginas web. +HTMLToPDF.defaultHeader=Habilitar encabezado predeterminado (Nombre y número de página) +HTMLToPDF.cssMediaType=Cambiar el tipo de medio CSS de la página. +HTMLToPDF.none=Ninguno +HTMLToPDF.print=Imprimir +HTMLToPDF.screen=Pantalla #AddStampRequest -AddStampRequest.header=Stamp PDF -AddStampRequest.title=Stamp PDF -AddStampRequest.stampType=Stamp Type -AddStampRequest.stampText=Stamp Text -AddStampRequest.stampImage=Stamp Image -AddStampRequest.alphabet=Alphabet -AddStampRequest.fontSize=Font/Image Size -AddStampRequest.rotation=Rotation -AddStampRequest.opacity=Opacity -AddStampRequest.position=Position -AddStampRequest.overrideX=Override X Coordinate -AddStampRequest.overrideY=Override Y Coordinate -AddStampRequest.customMargin=Custom Margin -AddStampRequest.customColor=Custom Text Color -AddStampRequest.submit=Submit +AddStampRequest.header=Sellar PDF +AddStampRequest.title=Sellar PDF +AddStampRequest.stampType=Tipo de sello +AddStampRequest.stampText=Texto del sello +AddStampRequest.stampImage=Imagen de sello +AddStampRequest.alphabet=Alfabeto +AddStampRequest.fontSize=Tamaño de fuente/imagen +AddStampRequest.rotation=Rotación +AddStampRequest.opacity=Opacidad +AddStampRequest.position=Posición +AddStampRequest.overrideX=Forzar coordenada X +AddStampRequest.overrideY=Forzar coordenada Y +AddStampRequest.customMargin=Personalizar margen +AddStampRequest.customColor=Personalizar color de texto +AddStampRequest.submit=Enviar #sanitizePDF sanitizePDF.title=Desinfectar archivo PDF @@ -584,11 +584,11 @@ scalePages.submit=Entregar certSign.title=Firma con certificado certSign.header=Firmar un PDF con su certificado (en desarrollo) certSign.selectPDF=Seleccione un archivo PDF para firmar: -certSign.jksNote=Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below. +certSign.jksNote=Nota: si el tipo de certificado no está enla lista de abajo, por favor conviértalo a un archivo almacén de claves de Java Java KeyStore (.jks) utilizando la herramienta línea de comandos. Posteriormente, seleccione en el listado de abajo la opción archivo .jks. certSign.selectKey=Seleccione su archivo de clave privada (formato PKCS#8, podría ser .pem o .der): certSign.selectCert=Seleccione su archivo de certificado (formato X.509, podría ser .pem o .der): certSign.selectP12=Seleccione su archivo de almacén de claves PKCS#12 (.p12 o .pfx) (Opcional, si se proporciona, debe contener su clave privada y certificado): -certSign.selectJKS=Select Your Java Keystore File (.jks or .keystore): +certSign.selectJKS=Seleccione su archivo de almacén de claves Java KeyStore (.jks or .keystore): certSign.certType=Tipo de certificado certSign.password=Introduzca su almacén de claves o contraseña de clave privada (si corresponde): certSign.showSig=Mostrar firma @@ -961,11 +961,11 @@ split-by-sections.submit=Dividir PDF #licenses -licenses.nav=Licenses -licenses.title=3rd Party Licenses -licenses.header=3rd Party Licenses -licenses.module=Module -licenses.version=Version -licenses.license=License +licenses.nav=Licencias +licenses.title=Licencias de terceros +licenses.header=Licencias de terceros +licenses.module=Módulo +licenses.version=Versión +licenses.license=Licencia diff --git a/src/main/resources/static/3rdPartyLicenses.json b/src/main/resources/static/3rdPartyLicenses.json index 699be591..c03dd84c 100644 --- a/src/main/resources/static/3rdPartyLicenses.json +++ b/src/main/resources/static/3rdPartyLicenses.json @@ -95,6 +95,13 @@ "moduleLicense": "MPL 2.0", "moduleLicenseUrl": "https://www.mozilla.org/en-US/MPL/2.0/" }, + { + "moduleName": "com.martiansoftware:jsap", + "moduleUrl": "http://www.martiansoftware.com/jsap/", + "moduleVersion": "2.1", + "moduleLicense": "LGPL", + "moduleLicenseUrl": "http://www.martiansoftware.com/jsap/license.html" + }, { "moduleName": "com.opencsv:opencsv", "moduleUrl": "http://opencsv.sf.net", @@ -204,31 +211,38 @@ "moduleLicense": "The Apache Software License, Version 2.0", "moduleLicenseUrl": "/LICENSE.txt" }, + { + "moduleName": "io.github.pixee:java-security-toolkit", + "moduleUrl": "https://github.com/pixee/java-security-toolkit", + "moduleVersion": "1.1.2", + "moduleLicense": "MIT License", + "moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php" + }, { "moduleName": "io.micrometer:micrometer-commons", "moduleUrl": "https://github.com/micrometer-metrics/micrometer", - "moduleVersion": "1.12.1", + "moduleVersion": "1.12.2", "moduleLicense": "The Apache Software License, Version 2.0", "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" }, { "moduleName": "io.micrometer:micrometer-core", "moduleUrl": "https://github.com/micrometer-metrics/micrometer", - "moduleVersion": "1.12.1", + "moduleVersion": "1.12.2", "moduleLicense": "The Apache Software License, Version 2.0", "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" }, { "moduleName": "io.micrometer:micrometer-jakarta9", "moduleUrl": "https://github.com/micrometer-metrics/micrometer", - "moduleVersion": "1.12.1", + "moduleVersion": "1.12.2", "moduleLicense": "The Apache Software License, Version 2.0", "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" }, { "moduleName": "io.micrometer:micrometer-observation", "moduleUrl": "https://github.com/micrometer-metrics/micrometer", - "moduleVersion": "1.12.1", + "moduleVersion": "1.12.2", "moduleLicense": "The Apache Software License, Version 2.0", "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" }, @@ -310,7 +324,7 @@ }, { "moduleName": "net.bytebuddy:byte-buddy", - "moduleVersion": "1.14.10", + "moduleVersion": "1.14.11", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt" }, @@ -385,21 +399,21 @@ { "moduleName": "org.apache.tomcat.embed:tomcat-embed-core", "moduleUrl": "https://tomcat.apache.org/", - "moduleVersion": "10.1.17", + "moduleVersion": "10.1.18", "moduleLicense": "Eclipse Public License - v 2.0", "moduleLicenseUrl": "https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt" }, { "moduleName": "org.apache.tomcat.embed:tomcat-embed-el", "moduleUrl": "https://tomcat.apache.org/", - "moduleVersion": "10.1.17", + "moduleVersion": "10.1.18", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" }, { "moduleName": "org.apache.tomcat.embed:tomcat-embed-websocket", "moduleUrl": "https://tomcat.apache.org/", - "moduleVersion": "10.1.17", + "moduleVersion": "10.1.18", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" }, @@ -582,14 +596,14 @@ { "moduleName": "org.slf4j:jul-to-slf4j", "moduleUrl": "http://www.slf4j.org", - "moduleVersion": "2.0.9", + "moduleVersion": "2.0.11", "moduleLicense": "MIT License", "moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php" }, { "moduleName": "org.slf4j:slf4j-api", "moduleUrl": "http://www.slf4j.org", - "moduleVersion": "2.0.9", + "moduleVersion": "2.0.11", "moduleLicense": "MIT License", "moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php" }, @@ -614,126 +628,126 @@ { "moduleName": "org.springframework.boot:spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-actuator", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-actuator-autoconfigure", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-autoconfigure", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-devtools", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter-actuator", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter-aop", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter-data-jpa", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter-jdbc", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter-json", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter-logging", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter-security", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter-thymeleaf", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter-tomcat", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.boot:spring-boot-starter-web", "moduleUrl": "https://spring.io/projects/spring-boot", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.data:spring-data-commons", "moduleUrl": "https://spring.io/projects/spring-data", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework.data:spring-data-jpa", "moduleUrl": "https://projects.spring.io/spring-data-jpa", - "moduleVersion": "3.2.1", + "moduleVersion": "3.2.2", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, @@ -768,77 +782,77 @@ { "moduleName": "org.springframework:spring-aop", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework:spring-aspects", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework:spring-beans", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework:spring-context", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework:spring-core", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework:spring-expression", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework:spring-jcl", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework:spring-jdbc", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework:spring-orm", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework:spring-tx", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, { "moduleName": "org.springframework:spring-web", "moduleUrl": "https://github.com/spring-projects/spring-framework", - "moduleVersion": "6.1.2", + "moduleVersion": "6.1.3", "moduleLicense": "Apache License, Version 2.0", "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0" }, diff --git a/src/main/resources/templates/remove-pages.html b/src/main/resources/templates/remove-pages.html index f86dc60e..ff4973f2 100644 --- a/src/main/resources/templates/remove-pages.html +++ b/src/main/resources/templates/remove-pages.html @@ -1,32 +1,38 @@ - - - - - - - -
-
-
-

-
-
-
-

- -
-
-
- - -
- -
-
-
-
-
-
-
- + + + + + + + + +
+
+
+

+
+
+
+

+ +
+
+
+ + +
+ +
+
+
+
+
+
+
+ + \ No newline at end of file