Compare commits
50 Commits
v0.20.2
...
normalize_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd07f789ce | ||
|
|
d725cf9a01 | ||
|
|
3dd0471e22 | ||
|
|
5a4efa81a7 | ||
|
|
ea59c12b27 | ||
|
|
9600f91dda | ||
|
|
a9f93b014a | ||
|
|
bf62e389f7 | ||
|
|
26af6b5636 | ||
|
|
0fabfea56d | ||
|
|
7a9417a62f | ||
|
|
eb45005baa | ||
|
|
a4f923eb3a | ||
|
|
e1c3561997 | ||
|
|
bf8b902100 | ||
|
|
8a5883501a | ||
|
|
fd8f3ce019 | ||
|
|
6f72096953 | ||
|
|
5a52e3d6dd | ||
|
|
23672cd18d | ||
|
|
68c0941666 | ||
|
|
96e399a617 | ||
|
|
22343e507d | ||
|
|
8a143d139c | ||
|
|
15ad46fe1c | ||
|
|
2473f0d034 | ||
|
|
f211eefc85 | ||
|
|
9da88b7652 | ||
|
|
729c8006d2 | ||
|
|
0d5b790443 | ||
|
|
aa16035137 | ||
|
|
41686883ee | ||
|
|
2e0790c893 | ||
|
|
4e937a6024 | ||
|
|
4af58118c9 | ||
|
|
aa2ad33c1d | ||
|
|
c7005bc07f | ||
|
|
3f932ebec9 | ||
|
|
296f265391 | ||
|
|
ca8519cb10 | ||
|
|
734d76a3b5 | ||
|
|
f5a39ed514 | ||
|
|
96f4e5eac7 | ||
|
|
d190ae0cf3 | ||
|
|
bb08a63296 | ||
|
|
3debc1b0df | ||
|
|
e560028097 | ||
|
|
5afcbdbc8b | ||
|
|
aaaf3ffe34 | ||
|
|
b043e666ae |
60
Dockerfile
@@ -1,5 +1,32 @@
|
||||
# Use the base image
|
||||
FROM frooodle/stirling-pdf-base:version8
|
||||
# Main stage
|
||||
FROM alpine:3.19.1
|
||||
|
||||
# JDK for app
|
||||
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
|
||||
libreoffice@testing \
|
||||
# OCR MY PDF (unpaper for descew and other advanced featues)
|
||||
ocrmypdf \
|
||||
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
|
||||
|
||||
|
||||
|
||||
ARG VERSION_TAG
|
||||
|
||||
@@ -12,36 +39,31 @@ ENV DOCKER_ENABLE_SECURITY=false \
|
||||
# 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 -p /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"]
|
||||
|
||||
@@ -1,65 +1,61 @@
|
||||
# Build jbig2enc in a separate stage
|
||||
FROM bellsoft/liberica-openjdk-debian:17
|
||||
# use alpine
|
||||
FROM alpine:3.19.1
|
||||
|
||||
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 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
|
||||
libreoffice@testing \
|
||||
# python and 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 && \
|
||||
# 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 -p /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
|
||||
# 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
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
# 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"]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Build jbig2enc in a separate stage
|
||||
FROM bellsoft/liberica-openjdk-alpine:17
|
||||
# use alpine
|
||||
FROM alpine:3.19.1
|
||||
|
||||
ARG VERSION_TAG
|
||||
|
||||
@@ -8,39 +8,44 @@ 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"]
|
||||
EXPOSE 8080
|
||||
|
||||
ENTRYPOINT ["tini", "--", "/scripts/init-without-ocr.sh"]
|
||||
|
||||
# Run the application
|
||||
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# Main stage
|
||||
FROM ubuntu:latest AS base
|
||||
|
||||
|
||||
|
||||
# JDK for app
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
openjdk-17-jre && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 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/*
|
||||
|
||||
|
||||
# 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
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 8.7 KiB |
@@ -1,310 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
width="99.537987mm"
|
||||
height="95.209366mm"
|
||||
viewBox="0 0 99.537987 95.209366"
|
||||
version="1.1"
|
||||
id="svg745"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 512 512"
|
||||
style="enable-background:new 0 0 512 512;"
|
||||
xml:space="preserve"
|
||||
inkscape:version="1.2.1 (9c6d41e4, 2022-07-14)"
|
||||
sodipodi:docname="stirling.svg"
|
||||
inkscape:export-filename="stirling.png"
|
||||
inkscape:export-xdpi="80"
|
||||
inkscape:export-ydpi="80"
|
||||
sodipodi:docname="favicon.svg"
|
||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||
inkscape:export-filename="favicon.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview747"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.914906"
|
||||
inkscape:cx="184.17193"
|
||||
inkscape:cy="509.88845"
|
||||
inkscape:window-width="2293"
|
||||
inkscape:window-height="1387"
|
||||
inkscape:window-x="122"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg745" /><defs
|
||||
id="defs742"><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient72198"><stop
|
||||
style="stop-color:#ccd6d7;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop72194" /><stop
|
||||
style="stop-color:#0f3a3f;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop72196" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient71928"><stop
|
||||
style="stop-color:#4b0005;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop71924" /><stop
|
||||
style="stop-color:#8f000c;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop71926" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient71920"><stop
|
||||
style="stop-color:#4b0005;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop71916" /><stop
|
||||
style="stop-color:#8f000c;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop71918" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient69598"><stop
|
||||
style="stop-color:#6a0007;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop69594" /><stop
|
||||
style="stop-color:#b8000f;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop69596" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient46361"><stop
|
||||
style="stop-color:#f7f6f8;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop46359" /><stop
|
||||
style="stop-color:#b7b7b5;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop46357" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient40554"><stop
|
||||
style="stop-color:#f4f2f4;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop40550" /><stop
|
||||
style="stop-color:#57767b;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop40552" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient39095"><stop
|
||||
style="stop-color:#285459;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop39093" /><stop
|
||||
style="stop-color:#a6b6af;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop39091" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient36672"><stop
|
||||
style="stop-color:#da453f;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop36668" /><stop
|
||||
style="stop-color:#a60008;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop36670" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient19524"><stop
|
||||
style="stop-color:#3a4b4f;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop19522" /><stop
|
||||
style="stop-color:#617979;stop-opacity:0.97461927;"
|
||||
offset="1"
|
||||
id="stop19520" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient17996"><stop
|
||||
style="stop-color:#401016;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop17994" /><stop
|
||||
style="stop-color:#761f19;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop17992" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient15569"><stop
|
||||
style="stop-color:#8ea8ad;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop15565" /><stop
|
||||
style="stop-color:#e9e7eb;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop15567" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient15557"><stop
|
||||
style="stop-color:#9b0e11;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop15553" /><stop
|
||||
style="stop-color:#370707;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop15555" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient15557"
|
||||
id="linearGradient15559"
|
||||
x1="120.06672"
|
||||
y1="63.25761"
|
||||
x2="135.16347"
|
||||
y2="78.078682"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient15569"
|
||||
id="linearGradient15571"
|
||||
x1="127.97037"
|
||||
y1="101.66144"
|
||||
x2="133.88971"
|
||||
y2="104.77026"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient17996"
|
||||
id="linearGradient17998"
|
||||
x1="117.9284"
|
||||
y1="86.055084"
|
||||
x2="130.67392"
|
||||
y2="76.945541"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient19524"
|
||||
id="linearGradient19528"
|
||||
x1="130.98172"
|
||||
y1="82.402977"
|
||||
x2="135.72115"
|
||||
y2="86.45166"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient36672"
|
||||
id="linearGradient36674"
|
||||
x1="63.797714"
|
||||
y1="74.81752"
|
||||
x2="96.636673"
|
||||
y2="120.29293"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient39095"
|
||||
id="linearGradient39097"
|
||||
x1="120.54506"
|
||||
y1="124.76902"
|
||||
x2="128.04152"
|
||||
y2="126.0704"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient40554"
|
||||
id="linearGradient40556"
|
||||
x1="113.84585"
|
||||
y1="114.04285"
|
||||
x2="119.65858"
|
||||
y2="128.50244"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient46361"
|
||||
id="linearGradient46363"
|
||||
x1="73.993439"
|
||||
y1="114.13906"
|
||||
x2="94.845322"
|
||||
y2="71.247383"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient69598"
|
||||
id="linearGradient69600"
|
||||
x1="95.854446"
|
||||
y1="114.66749"
|
||||
x2="103.77842"
|
||||
y2="120.1887"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient71920"
|
||||
id="linearGradient71922"
|
||||
x1="98.580376"
|
||||
y1="87.186958"
|
||||
x2="118.09738"
|
||||
y2="101.19449"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient71928"
|
||||
id="linearGradient71930"
|
||||
x1="78.278267"
|
||||
y1="97.433273"
|
||||
x2="92.313202"
|
||||
y2="104.33479"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient72198"
|
||||
id="linearGradient72200"
|
||||
x1="125.76636"
|
||||
y1="138.46817"
|
||||
x2="123.3327"
|
||||
y2="126.03291"
|
||||
gradientUnits="userSpaceOnUse" /></defs><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="background"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true"
|
||||
transform="translate(-51.420144,-44.470286)"><rect
|
||||
style="display:inline;fill:#ccd6d7;fill-opacity:1;stroke:none;stroke-width:4.13755;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.2"
|
||||
id="rect72067"
|
||||
width="99.481979"
|
||||
height="94.999512"
|
||||
x="51.476147"
|
||||
y="44.680138" /></g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer5"
|
||||
inkscape:label="shadow"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true"
|
||||
transform="translate(-51.420144,-44.470286)"><path
|
||||
style="display:inline;fill:url(#linearGradient72200);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 84.146049,134.73858 c 0,0 11.721038,2.48294 17.938661,2.91673 6.21763,0.43378 14.75251,0.59994 22.41237,-0.43379 8.01008,-1.081 13.19907,-2.22733 14.50043,-2.66112 1.30136,-0.43379 4.00784,-1.24297 4.15244,-2.25514 0.1446,-1.01217 -3.4703,-2.74733 -6.21763,-3.32571 -2.74732,-0.57838 -12.72444,-1.44596 -14.89337,-1.44596 -2.16894,0 -37.892901,7.20499 -37.892901,7.20499 z"
|
||||
id="path72192"
|
||||
sodipodi:nodetypes="cssssssc" /></g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Origami"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true"
|
||||
transform="translate(-51.420144,-44.470286)"><path
|
||||
style="display:inline;fill:url(#linearGradient40556);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 84.460552,134.86721 35.165798,-6.85679 16.15467,-42.7383 z"
|
||||
id="path960"
|
||||
sodipodi:nodetypes="cccc" /><path
|
||||
style="fill:url(#linearGradient15571);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 135.71493,85.428056 0.3984,45.049024 -9.66213,-20.46173 z"
|
||||
id="path964"
|
||||
sodipodi:nodetypes="cccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient39097);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 119.60518,128.00293 16.5337,2.48693 -9.68769,-20.5512 z"
|
||||
id="path966"
|
||||
sodipodi:nodetypes="cccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient15559);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 118.42209,57.022622 12.70423,-2.766809 -0.0785,25.087175 -12.43878,-13.376518 z"
|
||||
id="path968"
|
||||
sodipodi:nodetypes="ccccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient19528);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 135.72114,85.386768 -4.84219,-6.459493 0.0305,11.126604 z"
|
||||
id="path970"
|
||||
sodipodi:nodetypes="cccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient17998);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 119.10273,65.682415 11.96883,13.44935 -0.0899,10.819868 -11.88577,11.430427 z"
|
||||
id="path972"
|
||||
sodipodi:nodetypes="ccccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient36674);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 62.145635,130.15618 62.043392,65.435258 c 0,0 0.179321,-2.778132 1.89516,-4.036097 1.874923,-1.374597 4.341768,-1.894096 4.341768,-1.894096 l 50.91788,-11.349167 -0.0113,53.144272 -34.733274,33.56547 z"
|
||||
id="path958"
|
||||
sodipodi:nodetypes="ccsccccc" /></g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Letter"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true"
|
||||
transform="translate(-51.420144,-44.470286)"><path
|
||||
style="display:inline;fill:url(#linearGradient69600);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 94.780881,91.406803 16.870379,17.074877 -23.723345,23.00249 -18.122131,-17.99816 5.497473,-2.80607 18.404054,-0.0511 2.35163,-8.23071 z"
|
||||
id="path54894"
|
||||
sodipodi:nodetypes="cccccccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient71930);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 72.440405,92.224764 16.15467,15.745686 4.089788,-6.79927 z"
|
||||
id="path54892" /><path
|
||||
style="display:inline;fill:url(#linearGradient71922);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 95.138739,84.965385 1.124691,-14.109776 22.92453,22.286787 0.008,8.164604 -3.28863,3.16649 z"
|
||||
id="path54890"
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:label="path54890" /><path
|
||||
style="display:inline;fill:url(#linearGradient46363);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 95.138739,84.965385 h 1.226936 l -0.05112,-14.109776 c 0,0 -5.776827,-3.220709 -12.167126,-2.40275 -6.390296,0.817957 -8.151582,2.1248 -10.58233,4.396523 -1.90229,1.777838 -2.913974,3.527446 -3.987546,7.157132 -0.512646,1.733226 -0.281963,5.988892 0.613471,8.537436 0.664591,1.891528 2.453873,4.294281 4.958868,6.134686 2.662335,1.956002 8.281825,3.527443 8.281825,3.527443 0,0 5.134614,1.887351 5.572338,4.294281 0.308137,1.69437 -0.102243,3.22071 -1.635914,4.95887 -1.258314,1.42609 -3.62969,1.99377 -6.288054,1.07357 -2.658364,-0.92021 -6.139514,-3.85065 -7.106009,-4.90775 -0.817958,-0.89464 -2.820665,-3.06173 -2.890231,-4.294021 -0.01209,-0.214205 -1.229505,-0.0963 -1.229505,-0.0963 l -0.0723,14.256941 5.879073,2.24938 c 0,0 5.214483,1.78929 8.946415,1.43143 3.731934,-0.35786 7.617235,-0.51122 11.604778,-5.16336 3.987542,-4.65213 3.680812,-12.831715 2.147141,-15.899056 -1.533673,-3.067344 -3.561212,-6.138812 -10.480087,-8.281826 -5.776829,-1.789283 -7.872846,-3.01622 -8.128458,-4.396524 -0.255611,-1.380305 0.0091,-4.253646 2.760607,-5.214481 3.220711,-1.124693 5.623462,-0.05112 7.05489,1.12469 1.431425,1.175817 5.572339,5.623462 5.572339,5.623462 z"
|
||||
id="path46355"
|
||||
sodipodi:nodetypes="cccssssscssssscccssssssscc" /></g></svg>
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs173">
|
||||
|
||||
|
||||
<linearGradient
|
||||
id="XMLID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="304.496"
|
||||
y1="422.9102"
|
||||
x2="316.036"
|
||||
y2="326.2626">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#DCF1F3"
|
||||
id="stop156" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#C2C2C9"
|
||||
id="stop158" />
|
||||
</linearGradient>
|
||||
|
||||
</defs><sodipodi:namedview
|
||||
id="namedview171"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="219.91021"
|
||||
inkscape:cy="232.63813"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2054"
|
||||
inkscape:window-x="2869"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="XMLID_4_" />
|
||||
<style
|
||||
type="text/css"
|
||||
id="style150">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#C02223;}
|
||||
.st2{fill:#882425;}
|
||||
.st3{fill:url(#XMLID_5_);}
|
||||
.st4{fill:url(#XMLID_7_);}
|
||||
</style>
|
||||
|
||||
<g
|
||||
id="XMLID_4_">
|
||||
<path
|
||||
id="XMLID_131_"
|
||||
class="st1"
|
||||
d="M 347.01402,14.355825 98.978019,69.02261 C 73.825483,74.547445 55.942464,96.792175 55.942464,122.52628 v 315.06096 c 0,22.39012 16.719895,41.14548 38.819234,43.76251 L 224.8861,498.36042 339.48636,384.26465 455.76603,265.15425 453.73057,84.870162 C 453.43979,62.916214 433.08513,46.632491 411.71274,51.284984 l -28.78729,6.251786 0.14539,-13.666697 C 383.36162,24.678542 365.62399,10.284894 347.01402,14.355825 Z"
|
||||
sodipodi:nodetypes="ccssccccccccc"
|
||||
style="stroke-width:1.45391" /><path
|
||||
id="XMLID_117_"
|
||||
class="st2"
|
||||
d="m 383.21622,57.53677 v 285.8375 L 456.05681,265.00885 454.02135,78.763767 C 453.87595,59.863016 436.28372,45.905539 417.81914,49.97647 Z"
|
||||
style="stroke-width:1.45391" /><polygon
|
||||
id="XMLID_18_"
|
||||
class="st3"
|
||||
points="234.7,422.6 368.5,387.7 393.5,262.2 "
|
||||
style="fill:url(#XMLID_5_)"
|
||||
transform="matrix(1.4556308,0,0,1.4548265,-116.73161,-116.45231)" />
|
||||
<linearGradient
|
||||
id="XMLID_7_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="223.0838"
|
||||
y1="372.7559"
|
||||
x2="241.4174"
|
||||
y2="114.557"
|
||||
gradientTransform="matrix(1.4539039,0,0,1.4539039,-116.19976,-116.20474)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#DCF1F3"
|
||||
id="stop163" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#C2C2C9"
|
||||
id="stop165" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="XMLID_6_"
|
||||
class="st4"
|
||||
d="m 282.89686,214.84917 c 0,0 -22.24473,-28.93269 -38.67384,-36.78377 -10.46811,-4.94327 -26.02489,-6.83335 -38.23768,-0.72695 -18.02841,9.0142 -19.91848,34.31213 -3.34397,44.34406 3.92553,2.47165 9.15959,4.50711 15.99294,6.10641 36.63838,8.43264 97.12077,25.87949 89.70587,96.10304 0,0 -4.21633,65.86185 -73.56753,73.42215 -12.2128,1.30851 -24.57098,0.43617 -36.493,-2.32625 -16.42911,-3.63476 -45.50719,-11.04967 -59.75545,-19.91849 l -2.61703,-75.16682 h 6.97875 c 0,0 13.81208,33.43978 53.06749,49.57812 7.26952,2.90781 15.26599,4.07093 22.97168,2.90781 9.74116,-1.45391 21.22699,-6.68796 25.87949,-22.53551 0,0 7.85108,-23.11707 -32.85823,-35.76604 -32.56744,-10.17733 -63.24481,-20.64543 -75.89378,-54.95757 -5.961,-16.28371 -6.97874,-34.31212 -2.90781,-51.61358 5.37944,-22.53551 20.79082,-54.23062 64.40794,-67.89732 0,0 57.28381,-15.55677 96.53922,5.52484 l -1.74468,89.70587 z"
|
||||
style="fill:url(#XMLID_7_);stroke-width:1.45391" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -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;
|
||||
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
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package stirling.software.SPDF;
|
||||
|
||||
import io.github.pixee.security.SystemCommand;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import io.github.pixee.security.SystemCommand;
|
||||
|
||||
public class LibreOfficeListener {
|
||||
|
||||
private static final long ACTIVITY_TIMEOUT = 20 * 60 * 1000; // 20 minutes
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF;
|
||||
|
||||
import io.github.pixee.security.SystemCommand;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
@@ -11,6 +10,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
import io.github.pixee.security.SystemCommand;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import stirling.software.SPDF.config.ConfigInitializer;
|
||||
import stirling.software.SPDF.utils.GeneralUtils;
|
||||
|
||||
@@ -77,16 +77,11 @@ public class AppConfig {
|
||||
return Files.exists(Paths.get("/.dockerenv"));
|
||||
}
|
||||
|
||||
@Bean(name = "bookFormatsInstalled")
|
||||
public boolean bookFormatsInstalled() {
|
||||
return applicationProperties.getSystem().getCustomApplications().isInstallBookFormats();
|
||||
}
|
||||
|
||||
@Bean(name = "htmlFormatsInstalled")
|
||||
public boolean htmlFormatsInstalled() {
|
||||
@Bean(name = "bookAndHtmlFormatsInstalled")
|
||||
public boolean bookAndHtmlFormatsInstalled() {
|
||||
return applicationProperties
|
||||
.getSystem()
|
||||
.getCustomApplications()
|
||||
.isInstallAdvancedHtmlToPDF();
|
||||
.isInstallBookAndHtmlFormats();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.springframework.stereotype.Service;
|
||||
import stirling.software.SPDF.model.ApplicationProperties;
|
||||
|
||||
@Service
|
||||
@DependsOn({"bookFormatsInstalled"})
|
||||
@DependsOn({"bookAndHtmlFormatsInstalled"})
|
||||
public class EndpointConfiguration {
|
||||
private static final Logger logger = LoggerFactory.getLogger(EndpointConfiguration.class);
|
||||
private Map<String, Boolean> endpointStatuses = new ConcurrentHashMap<>();
|
||||
@@ -24,14 +24,14 @@ public class EndpointConfiguration {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
private boolean bookFormatsInstalled;
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
@Autowired
|
||||
public EndpointConfiguration(
|
||||
ApplicationProperties applicationProperties,
|
||||
@Qualifier("bookFormatsInstalled") boolean bookFormatsInstalled) {
|
||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
|
||||
this.applicationProperties = applicationProperties;
|
||||
this.bookFormatsInstalled = bookFormatsInstalled;
|
||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
||||
init();
|
||||
processEnvironmentConfigs();
|
||||
}
|
||||
@@ -229,7 +229,7 @@ public class EndpointConfiguration {
|
||||
private void processEnvironmentConfigs() {
|
||||
List<String> endpointsToRemove = applicationProperties.getEndpoints().getToRemove();
|
||||
List<String> groupsToRemove = applicationProperties.getEndpoints().getGroupsToRemove();
|
||||
if (!bookFormatsInstalled) {
|
||||
if (!bookAndHtmlFormatsInstalled) {
|
||||
groupsToRemove.add("Calibre");
|
||||
}
|
||||
if (endpointsToRemove != null) {
|
||||
|
||||
@@ -26,12 +26,8 @@ public class PostStartupProcesses {
|
||||
private boolean runningInDocker;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("bookFormatsInstalled")
|
||||
private boolean bookFormatsInstalled;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("htmlFormatsInstalled")
|
||||
private boolean htmlFormatsInstalled;
|
||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PostStartupProcesses.class);
|
||||
|
||||
@@ -39,34 +35,11 @@ public class PostStartupProcesses {
|
||||
public void runInstallCommandBasedOnEnvironment() throws IOException, InterruptedException {
|
||||
List<List<String>> commands = new ArrayList<>();
|
||||
// Checking for DOCKER_INSTALL_BOOK_FORMATS environment variable
|
||||
if (bookFormatsInstalled) {
|
||||
if (bookAndHtmlFormatsInstalled) {
|
||||
List<String> tmpList = new ArrayList<>();
|
||||
// Set up the timezone configuration commands
|
||||
tmpList.addAll(
|
||||
Arrays.asList(
|
||||
"sh",
|
||||
"-c",
|
||||
"echo 'tzdata tzdata/Areas select Europe' | debconf-set-selections; "
|
||||
+ "echo 'tzdata tzdata/Zones/Europe select Berlin' | debconf-set-selections"));
|
||||
commands.add(tmpList);
|
||||
|
||||
// Install calibre with DEBIAN_FRONTEND set to noninteractive
|
||||
tmpList = new ArrayList<>();
|
||||
tmpList.addAll(
|
||||
Arrays.asList(
|
||||
"sh",
|
||||
"-c",
|
||||
"DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends calibre"));
|
||||
commands.add(tmpList);
|
||||
}
|
||||
|
||||
// Checking for DOCKER_INSTALL_HTML_FORMATS environment variable
|
||||
if (htmlFormatsInstalled) {
|
||||
List<String> tmpList = new ArrayList<>();
|
||||
// Add -y flag for automatic yes to prompts and --no-install-recommends to reduce size
|
||||
tmpList.addAll(
|
||||
Arrays.asList(
|
||||
"apt-get", "install", "wkhtmltopdf", "-y", "--no-install-recommends"));
|
||||
tmpList.addAll(Arrays.asList("apk add --no-cache calibre"));
|
||||
commands.add(tmpList);
|
||||
}
|
||||
|
||||
@@ -74,8 +47,6 @@ public class PostStartupProcesses {
|
||||
// Run the command
|
||||
if (runningInDocker) {
|
||||
List<String> tmpList = new ArrayList<>();
|
||||
tmpList.addAll(Arrays.asList("apt-get", "update"));
|
||||
commands.add(0, tmpList);
|
||||
|
||||
for (List<String> list : commands) {
|
||||
ProcessExecutorResult returnCode =
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.awt.Color;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -22,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -137,6 +137,7 @@ public class MultiPageLayoutController {
|
||||
byte[] result = baos.toByteArray();
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
result,
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_layoutChanged.pdf");
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
+ "_layoutChanged.pdf");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -21,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -77,7 +77,8 @@ public class PdfOverlayController {
|
||||
overlay.overlay(overlayGuide).save(outputStream);
|
||||
byte[] data = outputStream.toByteArray();
|
||||
String outputFilename =
|
||||
Filenames.toSimpleFileName(baseFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
Filenames.toSimpleFileName(baseFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_overlayed.pdf"; // Remove file extension and append .pdf
|
||||
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -17,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -58,7 +58,9 @@ public class RearrangePagesPDFController {
|
||||
}
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_removed_pages.pdf");
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_removed_pages.pdf");
|
||||
}
|
||||
|
||||
private List<Integer> removeFirst(int totalPages) {
|
||||
@@ -212,7 +214,8 @@ public class RearrangePagesPDFController {
|
||||
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_rearranged.pdf");
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed rearranging documents", e);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
@@ -16,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -50,6 +50,8 @@ public class RotationController {
|
||||
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_rotated.pdf");
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_rotated.pdf");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
@@ -23,6 +22,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -113,6 +113,7 @@ public class ScalePagesController {
|
||||
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
baos.toByteArray(),
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_scaled.pdf");
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
+ "_scaled.pdf");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -24,6 +23,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class SplitPDFController {
|
||||
|
||||
PDDocument document = Loader.loadPDF(file.getBytes());
|
||||
|
||||
List<Integer> pageNumbers = request.getPageNumbersList(document);
|
||||
List<Integer> pageNumbers = request.getPageNumbersList(document, true);
|
||||
if (!pageNumbers.contains(document.getNumberOfPages() - 1))
|
||||
pageNumbers.add(document.getNumberOfPages() - 1);
|
||||
logger.info(
|
||||
@@ -84,7 +84,9 @@ public class SplitPDFController {
|
||||
|
||||
Path zipFile = Files.createTempFile("split_documents", ".zip");
|
||||
|
||||
String filename = Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "");
|
||||
String filename =
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "");
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
|
||||
// loop through the split documents and write them to the zip file
|
||||
for (int i = 0; i < splitDocumentsBoas.size(); i++) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -27,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -65,7 +65,9 @@ public class SplitPdfBySectionsController {
|
||||
sourceDocument.close();
|
||||
|
||||
Path zipFile = Files.createTempFile("split_documents", ".zip");
|
||||
String filename = Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "");
|
||||
String filename =
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "");
|
||||
byte[] data;
|
||||
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -21,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -121,7 +121,9 @@ public class SplitPdfBySizeController {
|
||||
sourceDocument.close();
|
||||
|
||||
Path zipFile = Files.createTempFile("split_documents", ".zip");
|
||||
String filename = Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "");
|
||||
String filename =
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "");
|
||||
byte[] data;
|
||||
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -10,6 +9,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -23,21 +23,21 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
public class ConvertBookToPDFController {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("bookFormatsInstalled")
|
||||
private boolean bookFormatsInstalled;
|
||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/book/pdf")
|
||||
@Operation(
|
||||
summary =
|
||||
"Convert a BOOK/comic (*.epub | *.mobi | *.azw3 | *.fb2 | *.txt | *.docx) to PDF",
|
||||
description =
|
||||
"(Requires bookFormatsInstalled flag and Calibre installed) This endpoint takes an BOOK/comic (*.epub | *.mobi | *.azw3 | *.fb2 | *.txt | *.docx) input and converts it to PDF format.")
|
||||
"(Requires bookAndHtmlFormatsInstalled flag and Calibre installed) This endpoint takes an BOOK/comic (*.epub | *.mobi | *.azw3 | *.fb2 | *.txt | *.docx) input and converts it to PDF format.")
|
||||
public ResponseEntity<byte[]> HtmlToPdf(@ModelAttribute GeneralFile request) throws Exception {
|
||||
MultipartFile fileInput = request.getFileInput();
|
||||
|
||||
if (!bookFormatsInstalled) {
|
||||
if (!bookAndHtmlFormatsInstalled) {
|
||||
throw new IllegalArgumentException(
|
||||
"bookFormatsInstalled flag is False, this functionality is not avaiable");
|
||||
"bookAndHtmlFormatsInstalled flag is False, this functionality is not avaiable");
|
||||
}
|
||||
|
||||
if (fileInput == null) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -10,6 +9,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -23,8 +23,8 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
public class ConvertHtmlToPDF {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("htmlFormatsInstalled")
|
||||
private boolean htmlFormatsInstalled;
|
||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
||||
@Operation(
|
||||
@@ -47,7 +47,10 @@ public class ConvertHtmlToPDF {
|
||||
}
|
||||
byte[] pdfBytes =
|
||||
FileToPdf.convertHtmlToPdf(
|
||||
request, fileInput.getBytes(), originalFilename, htmlFormatsInstalled);
|
||||
request,
|
||||
fileInput.getBytes(),
|
||||
originalFilename,
|
||||
bookAndHtmlFormatsInstalled);
|
||||
|
||||
String outputFilename =
|
||||
originalFilename.replaceFirst("[.][^.]+$", "")
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
import java.net.URLConnection;
|
||||
|
||||
@@ -19,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -57,7 +57,9 @@ public class ConvertImgPDFController {
|
||||
// returns bytes for image
|
||||
boolean singleImage = "single".equals(singleOrMultiple);
|
||||
byte[] result = null;
|
||||
String filename = Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "");
|
||||
String filename =
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "");
|
||||
try {
|
||||
result =
|
||||
PdfUtils.convertFromPdf(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -20,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -33,8 +33,8 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
public class ConvertMarkdownToPdf {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("htmlFormatsInstalled")
|
||||
private boolean htmlFormatsInstalled;
|
||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
||||
@Operation(
|
||||
@@ -69,7 +69,10 @@ public class ConvertMarkdownToPdf {
|
||||
|
||||
byte[] pdfBytes =
|
||||
FileToPdf.convertHtmlToPdf(
|
||||
null, htmlContent.getBytes(), "converted.html", htmlFormatsInstalled);
|
||||
null,
|
||||
htmlContent.getBytes(),
|
||||
"converted.html",
|
||||
bookAndHtmlFormatsInstalled);
|
||||
|
||||
String outputFilename =
|
||||
originalFilename.replaceFirst("[.][^.]+$", "")
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -17,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -90,7 +90,8 @@ public class ConvertOfficeController {
|
||||
byte[] pdfByteArray = convertToPdf(inputFile);
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
pdfByteArray,
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_convertedToPDF.pdf");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
@@ -16,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -30,22 +30,22 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
public class ConvertPDFToBookController {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("bookFormatsInstalled")
|
||||
private boolean bookFormatsInstalled;
|
||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/pdf/book")
|
||||
@Operation(
|
||||
summary =
|
||||
"Convert a PDF to a Book/comic (*.epub | *.mobi | *.azw3 | *.fb2 | *.txt | *.docx .. (others to include by chatgpt) to PDF",
|
||||
description =
|
||||
"(Requires bookFormatsInstalled flag and Calibre installed) This endpoint Convert a PDF to a Book/comic (*.epub | *.mobi | *.azw3 | *.fb2 | *.txt | *.docx .. (others to include by chatgpt) to PDF")
|
||||
"(Requires bookAndHtmlFormatsInstalled flag and Calibre installed) This endpoint Convert a PDF to a Book/comic (*.epub | *.mobi | *.azw3 | *.fb2 | *.txt | *.docx .. (others to include by chatgpt) to PDF")
|
||||
public ResponseEntity<byte[]> HtmlToPdf(@ModelAttribute PdfToBookRequest request)
|
||||
throws Exception {
|
||||
MultipartFile fileInput = request.getFileInput();
|
||||
|
||||
if (!bookFormatsInstalled) {
|
||||
if (!bookAndHtmlFormatsInstalled) {
|
||||
throw new IllegalArgumentException(
|
||||
"bookFormatsInstalled flag is False, this functionality is not avaiable");
|
||||
"bookAndHtmlFormatsInstalled flag is False, this functionality is not avaiable");
|
||||
}
|
||||
|
||||
if (fileInput == null) {
|
||||
@@ -93,7 +93,8 @@ public class ConvertPDFToBookController {
|
||||
}
|
||||
|
||||
String outputFilename =
|
||||
Filenames.toSimpleFileName(fileInput.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
Filenames.toSimpleFileName(fileInput.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "."
|
||||
+ outputFormat; // Remove file extension and append .pdf
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@ package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.text.PDFTextStripper;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -9,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -17,6 +22,7 @@ import stirling.software.SPDF.model.api.converters.PdfToPresentationRequest;
|
||||
import stirling.software.SPDF.model.api.converters.PdfToTextOrRTFRequest;
|
||||
import stirling.software.SPDF.model.api.converters.PdfToWordRequest;
|
||||
import stirling.software.SPDF.utils.PDFToFile;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/convert")
|
||||
@@ -59,9 +65,21 @@ public class ConvertPDFToOffice {
|
||||
throws IOException, InterruptedException {
|
||||
MultipartFile inputFile = request.getFileInput();
|
||||
String outputFormat = request.getOutputFormat();
|
||||
|
||||
PDFToFile pdfToFile = new PDFToFile();
|
||||
return pdfToFile.processPdfToOfficeFormat(inputFile, outputFormat, "writer_pdf_import");
|
||||
if ("txt".equals(request.getOutputFormat())) {
|
||||
try (PDDocument document = Loader.loadPDF(inputFile.getBytes())) {
|
||||
PDFTextStripper stripper = new PDFTextStripper();
|
||||
String text = stripper.getText(document);
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
text.getBytes(),
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ ".txt",
|
||||
MediaType.TEXT_PLAIN);
|
||||
}
|
||||
} else {
|
||||
PDFToFile pdfToFile = new PDFToFile();
|
||||
return pdfToFile.processPdfToOfficeFormat(inputFile, outputFormat, "writer_pdf_import");
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/pdf/word")
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.converters;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
@@ -13,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -64,7 +64,9 @@ public class ConvertPDFToPDFA {
|
||||
|
||||
// Return the optimized PDF as a response
|
||||
String outputFilename =
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_PDFA.pdf";
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_PDFA.pdf";
|
||||
return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
public class ConvertWebsiteToPDF {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("htmlFormatsInstalled")
|
||||
private boolean htmlFormatsInstalled;
|
||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||
private boolean bookAndHtmlFormatsInstalled;
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/url/pdf")
|
||||
@Operation(
|
||||
@@ -53,7 +53,7 @@ public class ConvertWebsiteToPDF {
|
||||
|
||||
// Prepare the OCRmyPDF command
|
||||
List<String> command = new ArrayList<>();
|
||||
if (!htmlFormatsInstalled) {
|
||||
if (!bookAndHtmlFormatsInstalled) {
|
||||
command.add("weasyprint");
|
||||
} else {
|
||||
command.add("wkhtmltopdf");
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.filters;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
@@ -14,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
@@ -19,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -134,7 +134,8 @@ public class AutoRenameController {
|
||||
return WebResponseUtils.pdfDocToWebResponse(document, header + ".pdf");
|
||||
} else {
|
||||
logger.info("File has no good title to be found");
|
||||
return WebResponseUtils.pdfDocToWebResponse(document, Filenames.toSimpleFileName(file.getOriginalFilename()));
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document, Filenames.toSimpleFileName(file.getOriginalFilename()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.DataBufferInt;
|
||||
@@ -32,6 +31,7 @@ import com.google.zxing.PlanarYUVLuminanceSource;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -98,7 +98,9 @@ public class AutoSplitPdfController {
|
||||
document.close();
|
||||
|
||||
Path zipFile = Files.createTempFile("split_documents", ".zip");
|
||||
String filename = Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "");
|
||||
String filename =
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "");
|
||||
byte[] data;
|
||||
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
|
||||
|
||||
@@ -1,25 +1,21 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
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.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@@ -28,12 +24,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import stirling.software.SPDF.model.api.misc.RemoveBlankPagesRequest;
|
||||
import stirling.software.SPDF.utils.PdfUtils;
|
||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
|
||||
@RestController
|
||||
@@ -41,6 +37,8 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
||||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||
public class BlankPageController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BlankPageController.class);
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/remove-blanks")
|
||||
@Operation(
|
||||
summary = "Remove blank pages from a PDF file",
|
||||
@@ -63,63 +61,35 @@ public class BlankPageController {
|
||||
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||
|
||||
for (PDPage page : pages) {
|
||||
System.out.println("checking page " + pageIndex);
|
||||
logger.info("checking page " + pageIndex);
|
||||
textStripper.setStartPage(pageIndex + 1);
|
||||
textStripper.setEndPage(pageIndex + 1);
|
||||
String pageText = textStripper.getText(document);
|
||||
boolean hasText = !pageText.trim().isEmpty();
|
||||
|
||||
Boolean blank = false;
|
||||
if (hasText) {
|
||||
pagesToKeepIndex.add(pageIndex);
|
||||
System.out.println("page " + pageIndex + " has text");
|
||||
logger.info("page " + pageIndex + " has text, not blank");
|
||||
blank = false;
|
||||
} else {
|
||||
boolean hasImages = PdfUtils.hasImagesOnPage(page);
|
||||
if (hasImages) {
|
||||
System.out.println("page " + pageIndex + " has image");
|
||||
|
||||
Path tempFile = Files.createTempFile("image_", ".png");
|
||||
|
||||
logger.info("page " + pageIndex + " has image, running blank detection");
|
||||
// Render image and save as temp file
|
||||
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 300);
|
||||
ImageIO.write(image, "png", tempFile.toFile());
|
||||
|
||||
List<String> command =
|
||||
new ArrayList<>(
|
||||
Arrays.asList(
|
||||
"python",
|
||||
System.getProperty("user.dir")
|
||||
+ "/scripts/detect-blank-pages.py",
|
||||
tempFile.toString(),
|
||||
"--threshold",
|
||||
String.valueOf(threshold),
|
||||
"--white_percent",
|
||||
String.valueOf(whitePercent)));
|
||||
|
||||
Boolean blank = false;
|
||||
// Run CLI command
|
||||
try {
|
||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.PYTHON_OPENCV)
|
||||
.runCommandWithOutputHandling(command);
|
||||
} catch (IOException e) {
|
||||
// From detect-blank-pages.py
|
||||
// Return code 1: The image is considered blank.
|
||||
// Return code 0: The image is not considered blank.
|
||||
// Since the process returned with a failure code, it should be blank.
|
||||
blank = true;
|
||||
}
|
||||
|
||||
if (blank) {
|
||||
System.out.println("Skipping, Image was blank for page #" + pageIndex);
|
||||
} else {
|
||||
System.out.println(
|
||||
"page " + pageIndex + " has image which is not blank");
|
||||
pagesToKeepIndex.add(pageIndex);
|
||||
}
|
||||
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 30);
|
||||
blank = isBlankImage(image, threshold, whitePercent, threshold);
|
||||
}
|
||||
}
|
||||
|
||||
if (blank) {
|
||||
logger.info("Skipping, Image was blank for page #" + pageIndex);
|
||||
} else {
|
||||
logger.info("page " + pageIndex + " has image which is not blank");
|
||||
pagesToKeepIndex.add(pageIndex);
|
||||
}
|
||||
|
||||
pageIndex++;
|
||||
}
|
||||
System.out.print("pagesToKeep=" + pagesToKeepIndex.size());
|
||||
|
||||
// Remove pages not present in pagesToKeepIndex
|
||||
List<Integer> pageIndices =
|
||||
IntStream.range(0, pages.getCount()).boxed().collect(Collectors.toList());
|
||||
@@ -132,7 +102,8 @@ public class BlankPageController {
|
||||
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_blanksRemoved.pdf");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@@ -141,4 +112,30 @@ public class BlankPageController {
|
||||
if (document != null) document.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBlankImage(
|
||||
BufferedImage image, int threshold, double whitePercent, int blurSize) {
|
||||
if (image == null) {
|
||||
logger.info("Error: Image is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert to binary image based on the threshold
|
||||
int whitePixels = 0;
|
||||
int totalPixels = image.getWidth() * image.getHeight();
|
||||
|
||||
for (int i = 0; i < image.getHeight(); i++) {
|
||||
for (int j = 0; j < image.getWidth(); j++) {
|
||||
int color = image.getRGB(j, i) & 0xFF;
|
||||
if (color >= 255 - threshold) {
|
||||
whitePixels++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double whitePixelPercentage = (whitePixels / (double) totalPixels) * 100;
|
||||
logger.info(String.format("Page has white pixel percent of %.2f%%", whitePixelPercentage));
|
||||
|
||||
return whitePixelPercentage >= whitePercent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -30,6 +29,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -265,7 +265,9 @@ public class CompressController {
|
||||
|
||||
// Return the optimized PDF as a response
|
||||
String outputFilename =
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_Optimized.pdf";
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_Optimized.pdf";
|
||||
return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -30,6 +29,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -67,7 +67,9 @@ public class ExtractImagesController {
|
||||
zos.setLevel(Deflater.BEST_COMPRESSION);
|
||||
|
||||
int imageIndex = 1;
|
||||
String filename = Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "");
|
||||
String filename =
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "");
|
||||
int pageNum = 0;
|
||||
Set<Integer> processedImages = new HashSet<>();
|
||||
// Iterate over each page
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.awt.Color;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.AffineTransformOp;
|
||||
@@ -34,6 +33,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -142,7 +142,9 @@ public class FakeScanControllerWIP {
|
||||
|
||||
// Return the optimized PDF as a response
|
||||
String outputFilename =
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_scanned.pdf";
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_scanned.pdf";
|
||||
return WebResponseUtils.boasToWebResponse(baos, outputFilename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -19,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -165,6 +165,8 @@ public class MetadataController {
|
||||
document.setDocumentInformation(info);
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_metadata.pdf");
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_metadata.pdf");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -25,6 +24,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -183,12 +183,16 @@ public class OCRController {
|
||||
|
||||
// Return the OCR processed PDF as a response
|
||||
String outputFilename =
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_OCR.pdf";
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_OCR.pdf";
|
||||
|
||||
if (sidecar != null && sidecar) {
|
||||
// Create a zip file containing both the PDF and the text file
|
||||
String outputZipFilename =
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_OCR.zip";
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_OCR.zip";
|
||||
Path tempZipFile = Files.createTempFile("output_", ".zip");
|
||||
|
||||
try (ZipOutputStream zipOut =
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -13,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -45,7 +45,9 @@ public class OverlayImageController {
|
||||
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
result,
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_overlayed.pdf");
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_overlayed.pdf");
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to add image to PDF", e);
|
||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@@ -22,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -146,7 +146,8 @@ public class PageNumbersController {
|
||||
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
baos.toByteArray(),
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_numbersAdded.pdf",
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
+ "_numbersAdded.pdf",
|
||||
MediaType.APPLICATION_PDF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -16,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -66,7 +66,9 @@ public class RepairController {
|
||||
|
||||
// Return the optimized PDF as a response
|
||||
String outputFilename =
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_repaired.pdf";
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_repaired.pdf";
|
||||
return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -17,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -55,7 +55,8 @@ public class ShowJavascript {
|
||||
|
||||
script +=
|
||||
"// File: "
|
||||
+ Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
+ Filenames.toSimpleFileName(
|
||||
inputFile.getOriginalFilename())
|
||||
+ ", Script: "
|
||||
+ name
|
||||
+ "\n"
|
||||
@@ -67,12 +68,14 @@ 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(
|
||||
script.getBytes(StandardCharsets.UTF_8),
|
||||
inputFile.getOriginalFilename() + ".js");
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()) + ".js");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.misc;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
@@ -8,6 +7,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -48,13 +49,13 @@ public class StampController {
|
||||
@Operation(
|
||||
summary = "Add stamp to a PDF file",
|
||||
description =
|
||||
"This endpoint adds a stamp to a given PDF file. Users can specify the watermark type (text or image), rotation, opacity, width spacer, and height spacer. Input:PDF Output:PDF Type:SISO")
|
||||
"This endpoint adds a stamp to a given PDF file. Users can specify the stamp type (text or image), rotation, opacity, width spacer, and height spacer. Input:PDF Output:PDF Type:SISO")
|
||||
public ResponseEntity<byte[]> addStamp(@ModelAttribute AddStampRequest request)
|
||||
throws IOException, Exception {
|
||||
MultipartFile pdfFile = request.getFileInput();
|
||||
String watermarkType = request.getStampType();
|
||||
String watermarkText = request.getStampText();
|
||||
MultipartFile watermarkImage = request.getStampImage();
|
||||
String stampType = request.getStampType();
|
||||
String stampText = request.getStampText();
|
||||
MultipartFile stampImage = request.getStampImage();
|
||||
String alphabet = request.getAlphabet();
|
||||
float fontSize = request.getFontSize();
|
||||
float rotation = request.getRotation();
|
||||
@@ -65,6 +66,7 @@ public class StampController {
|
||||
|
||||
String customColor = request.getCustomColor();
|
||||
float marginFactor;
|
||||
|
||||
switch (request.getCustomMargin().toLowerCase()) {
|
||||
case "small":
|
||||
marginFactor = 0.02f;
|
||||
@@ -78,7 +80,6 @@ public class StampController {
|
||||
case "x-large":
|
||||
marginFactor = 0.075f;
|
||||
break;
|
||||
|
||||
default:
|
||||
marginFactor = 0.035f;
|
||||
break;
|
||||
@@ -87,54 +88,64 @@ public class StampController {
|
||||
// Load the input PDF
|
||||
PDDocument document = Loader.loadPDF(pdfFile.getBytes());
|
||||
|
||||
for (PDPage page : document.getPages()) {
|
||||
PDPageContentStream contentStream =
|
||||
new PDPageContentStream(
|
||||
document, page, PDPageContentStream.AppendMode.APPEND, true, true);
|
||||
List<Integer> pageNumbers = request.getPageNumbersList(document, false);
|
||||
|
||||
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
|
||||
graphicsState.setNonStrokingAlphaConstant(opacity);
|
||||
contentStream.setGraphicsStateParameters(graphicsState);
|
||||
for (int pageIndex : pageNumbers) {
|
||||
int zeroBasedIndex = pageIndex - 1;
|
||||
if (zeroBasedIndex >= 0 && zeroBasedIndex < document.getNumberOfPages()) {
|
||||
PDPage page = document.getPage(zeroBasedIndex);
|
||||
PDRectangle pageSize = page.getMediaBox();
|
||||
float margin = marginFactor * (pageSize.getWidth() + pageSize.getHeight()) / 2;
|
||||
|
||||
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);
|
||||
PDPageContentStream contentStream =
|
||||
new PDPageContentStream(
|
||||
document, page, PDPageContentStream.AppendMode.APPEND, true, true);
|
||||
|
||||
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
|
||||
graphicsState.setNonStrokingAlphaConstant(opacity);
|
||||
contentStream.setGraphicsStateParameters(graphicsState);
|
||||
|
||||
if ("text".equalsIgnoreCase(stampType)) {
|
||||
addTextStamp(
|
||||
contentStream,
|
||||
stampText,
|
||||
document,
|
||||
page,
|
||||
rotation,
|
||||
position,
|
||||
fontSize,
|
||||
alphabet,
|
||||
overrideX,
|
||||
overrideY,
|
||||
margin,
|
||||
customColor);
|
||||
} else if ("image".equalsIgnoreCase(stampType)) {
|
||||
addImageStamp(
|
||||
contentStream,
|
||||
stampImage,
|
||||
document,
|
||||
page,
|
||||
rotation,
|
||||
position,
|
||||
fontSize,
|
||||
overrideX,
|
||||
overrideY,
|
||||
margin);
|
||||
}
|
||||
|
||||
contentStream.close();
|
||||
}
|
||||
|
||||
contentStream.close();
|
||||
}
|
||||
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_watermarked.pdf");
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_stamped.pdf");
|
||||
}
|
||||
|
||||
private void addTextStamp(
|
||||
PDPageContentStream contentStream,
|
||||
String watermarkText,
|
||||
String stampText,
|
||||
PDDocument document,
|
||||
PDPage page,
|
||||
float rotation,
|
||||
@@ -143,7 +154,7 @@ public class StampController {
|
||||
String alphabet,
|
||||
float overrideX, // X override
|
||||
float overrideY,
|
||||
float marginFactor,
|
||||
float margin,
|
||||
String colorString) // Y override
|
||||
throws IOException {
|
||||
String resourceDir = "";
|
||||
@@ -203,27 +214,21 @@ public class StampController {
|
||||
x = overrideX;
|
||||
y = overrideY;
|
||||
} else {
|
||||
x =
|
||||
calculatePositionX(
|
||||
pageSize,
|
||||
position,
|
||||
fontSize,
|
||||
font,
|
||||
fontSize,
|
||||
watermarkText,
|
||||
marginFactor);
|
||||
y = calculatePositionY(pageSize, position, fontSize, marginFactor);
|
||||
x = calculatePositionX(pageSize, position, fontSize, font, fontSize, stampText, margin);
|
||||
y =
|
||||
calculatePositionY(
|
||||
pageSize, position, calculateTextCapHeight(font, fontSize), margin);
|
||||
}
|
||||
|
||||
contentStream.beginText();
|
||||
contentStream.setTextMatrix(Matrix.getRotateInstance(Math.toRadians(rotation), x, y));
|
||||
contentStream.showText(watermarkText);
|
||||
contentStream.showText(stampText);
|
||||
contentStream.endText();
|
||||
}
|
||||
|
||||
private void addImageStamp(
|
||||
PDPageContentStream contentStream,
|
||||
MultipartFile watermarkImage,
|
||||
MultipartFile stampImage,
|
||||
PDDocument document,
|
||||
PDPage page,
|
||||
float rotation,
|
||||
@@ -231,11 +236,11 @@ public class StampController {
|
||||
float fontSize,
|
||||
float overrideX,
|
||||
float overrideY,
|
||||
float marginFactor)
|
||||
float margin)
|
||||
throws IOException {
|
||||
|
||||
// Load the watermark image
|
||||
BufferedImage image = ImageIO.read(watermarkImage.getInputStream());
|
||||
// Load the stamp image
|
||||
BufferedImage image = ImageIO.read(stampImage.getInputStream());
|
||||
|
||||
// Compute width based on original aspect ratio
|
||||
float aspectRatio = (float) image.getWidth() / (float) image.getHeight();
|
||||
@@ -257,10 +262,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();
|
||||
@@ -277,17 +280,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;
|
||||
}
|
||||
@@ -297,17 +314,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.pipeline;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.github.pixee.security.ZipSecurity;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
@@ -38,6 +36,9 @@ import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.github.pixee.security.ZipSecurity;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import stirling.software.SPDF.SPdfApplication;
|
||||
import stirling.software.SPDF.model.PipelineConfig;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.security;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -43,6 +42,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -124,7 +124,9 @@ public class CertSignController {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
sign(pdf.getBytes(), baos, createSignature, name, location, reason);
|
||||
return WebResponseUtils.boasToWebResponse(
|
||||
baos, Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_signed.pdf");
|
||||
baos,
|
||||
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
+ "_signed.pdf");
|
||||
}
|
||||
|
||||
private static void sign(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.security;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
@@ -16,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -44,7 +44,8 @@ public class PasswordController {
|
||||
document.setAllSecurityToBeRemoved(true);
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(fileInput.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
Filenames.toSimpleFileName(fileInput.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_password_removed.pdf");
|
||||
}
|
||||
|
||||
@@ -89,10 +90,13 @@ public class PasswordController {
|
||||
if ("".equals(ownerPassword) && "".equals(password))
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(fileInput.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
Filenames.toSimpleFileName(fileInput.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_permissions.pdf");
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(fileInput.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_passworded.pdf");
|
||||
Filenames.toSimpleFileName(fileInput.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_passworded.pdf");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.security;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -26,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -105,7 +105,8 @@ public class RedactController {
|
||||
byte[] pdfContent = baos.toByteArray();
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
pdfContent,
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_redacted.pdf");
|
||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
+ "_redacted.pdf");
|
||||
}
|
||||
|
||||
private void redactFoundText(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.security;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
@@ -29,6 +28,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -77,7 +77,8 @@ public class SanitizeController {
|
||||
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_sanitized.pdf");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.controller.api.security;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
@@ -32,6 +31,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@@ -106,7 +106,9 @@ public class WatermarkController {
|
||||
|
||||
return WebResponseUtils.pdfDocToWebResponse(
|
||||
document,
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + "_watermarked.pdf");
|
||||
Filenames.toSimpleFileName(pdfFile.getOriginalFilename())
|
||||
.replaceFirst("[.][^.]+$", "")
|
||||
+ "_watermarked.pdf");
|
||||
}
|
||||
|
||||
private void addTextWatermark(
|
||||
|
||||
@@ -13,7 +13,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
public class ConverterWebController {
|
||||
|
||||
@ConditionalOnExpression("#{bookFormatsInstalled}")
|
||||
@ConditionalOnExpression("#{bookAndHtmlFormatsInstalled}")
|
||||
@GetMapping("/book-to-pdf")
|
||||
@Hidden
|
||||
public String convertBookToPdfForm(Model model) {
|
||||
@@ -21,7 +21,7 @@ public class ConverterWebController {
|
||||
return "convert/book-to-pdf";
|
||||
}
|
||||
|
||||
@ConditionalOnExpression("#{bookFormatsInstalled}")
|
||||
@ConditionalOnExpression("#{bookAndHtmlFormatsInstalled}")
|
||||
@GetMapping("/pdf-to-book")
|
||||
@Hidden
|
||||
public String convertPdfToBookForm(Model model) {
|
||||
|
||||
@@ -290,31 +290,20 @@ public class ApplicationProperties {
|
||||
}
|
||||
|
||||
public static class CustomApplications {
|
||||
private boolean installBookFormats;
|
||||
private boolean installAdvancedHtmlToPDF;
|
||||
private boolean installBookAndHtmlFormats;
|
||||
|
||||
public boolean isInstallBookFormats() {
|
||||
return installBookFormats;
|
||||
public boolean isInstallBookAndHtmlFormats() {
|
||||
return installBookAndHtmlFormats;
|
||||
}
|
||||
|
||||
public void setInstallBookFormats(boolean installBookFormats) {
|
||||
this.installBookFormats = installBookFormats;
|
||||
}
|
||||
|
||||
public boolean isInstallAdvancedHtmlToPDF() {
|
||||
return installAdvancedHtmlToPDF;
|
||||
}
|
||||
|
||||
public void setInstallAdvancedHtmlToPDF(boolean installAdvancedHtmlToPDF) {
|
||||
this.installAdvancedHtmlToPDF = installAdvancedHtmlToPDF;
|
||||
public void setInstallBookAndHtmlFormats(boolean installBookAndHtmlFormats) {
|
||||
this.installBookAndHtmlFormats = installBookAndHtmlFormats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CustomApplications [installBookFormats="
|
||||
+ installBookFormats
|
||||
+ ", installAdvancedHtmlToPDF="
|
||||
+ installAdvancedHtmlToPDF
|
||||
return "CustomApplications [installBookAndHtmlFormats="
|
||||
+ installBookAndHtmlFormats
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ public class PDFWithPageNums extends PDFFile {
|
||||
private String pageNumbers;
|
||||
|
||||
@Hidden
|
||||
public List<Integer> getPageNumbersList() {
|
||||
public List<Integer> getPageNumbersList(boolean zeroCount) {
|
||||
int pageCount = 0;
|
||||
try {
|
||||
pageCount = Loader.loadPDF(getFileInput().getBytes()).getNumberOfPages();
|
||||
@@ -33,13 +33,13 @@ public class PDFWithPageNums extends PDFFile {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return GeneralUtils.parsePageString(pageNumbers, pageCount);
|
||||
return GeneralUtils.parsePageString(pageNumbers, pageCount, zeroCount);
|
||||
}
|
||||
|
||||
@Hidden
|
||||
public List<Integer> getPageNumbersList(PDDocument doc) {
|
||||
public List<Integer> getPageNumbersList(PDDocument doc, boolean zeroCount) {
|
||||
int pageCount = 0;
|
||||
pageCount = doc.getNumberOfPages();
|
||||
return GeneralUtils.parsePageString(pageNumbers, pageCount);
|
||||
return GeneralUtils.parsePageString(pageNumbers, pageCount, zeroCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,39 +14,4 @@ public class HTMLToPdfRequest extends PDFFile {
|
||||
description = "Zoom level for displaying the website. Default is '1'.",
|
||||
defaultValue = "1")
|
||||
private float zoom;
|
||||
|
||||
@Schema(description = "Width of the page in centimeters.")
|
||||
private Float pageWidth;
|
||||
|
||||
@Schema(description = "Height of the page in centimeters.")
|
||||
private Float pageHeight;
|
||||
|
||||
@Schema(description = "Top margin of the page in millimeters.")
|
||||
private Float marginTop;
|
||||
|
||||
@Schema(description = "Bottom margin of the page in millimeters.")
|
||||
private Float marginBottom;
|
||||
|
||||
@Schema(description = "Left margin of the page in millimeters.")
|
||||
private Float marginLeft;
|
||||
|
||||
@Schema(description = "Right margin of the page in millimeters.")
|
||||
private Float marginRight;
|
||||
|
||||
@Schema(
|
||||
description = "Enable or disable rendering of website background.",
|
||||
allowableValues = {"Yes", "No"})
|
||||
private String printBackground;
|
||||
|
||||
@Schema(
|
||||
description =
|
||||
"Enable or disable the default header. The default header includes the name of the page on the left and the page number on the right.",
|
||||
allowableValues = {"Yes", "No"})
|
||||
private String defaultHeader;
|
||||
|
||||
@Schema(
|
||||
description = "Change the CSS media type of the page. Defaults to 'print'.",
|
||||
allowableValues = {"none", "print", "screen"},
|
||||
defaultValue = "print")
|
||||
private String cssMediaType;
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import stirling.software.SPDF.model.api.PDFFile;
|
||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class AddStampRequest extends PDFFile {
|
||||
public class AddStampRequest extends PDFWithPageNums {
|
||||
|
||||
@Schema(
|
||||
description = "The stamp type (text or image)",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package stirling.software.SPDF.utils;
|
||||
|
||||
import io.github.pixee.security.ZipSecurity;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
@@ -13,6 +13,8 @@ import java.util.stream.Stream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import io.github.pixee.security.ZipSecurity;
|
||||
|
||||
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||
|
||||
@@ -33,95 +35,40 @@ public class FileToPdf {
|
||||
tempInputFile = Files.createTempFile("input_", ".html");
|
||||
Files.write(tempInputFile, fileBytes);
|
||||
} else {
|
||||
tempInputFile = unzipAndGetMainHtml(fileBytes);
|
||||
tempInputFile = Files.createTempFile("input_", ".zip");
|
||||
Files.write(tempInputFile, fileBytes);
|
||||
}
|
||||
|
||||
List<String> command = new ArrayList<>();
|
||||
if (!htmlFormatsInstalled) {
|
||||
command.add("weasyprint");
|
||||
} else {
|
||||
command.add("wkhtmltopdf");
|
||||
command.add("--enable-local-file-access");
|
||||
command.add("--load-error-handling");
|
||||
command.add("ignore");
|
||||
command.add("--load-media-error-handling");
|
||||
command.add("ignore");
|
||||
command.add("--zoom");
|
||||
command.add(String.valueOf(request.getZoom()));
|
||||
command.add(tempInputFile.toString());
|
||||
command.add(tempOutputFile.toString());
|
||||
|
||||
} else {
|
||||
command.add("ebook-convert");
|
||||
command.add(tempInputFile.toString());
|
||||
command.add(tempOutputFile.toString());
|
||||
command.add("--paper-size");
|
||||
command.add("a4");
|
||||
|
||||
// if custom zoom add zoom style direct to html
|
||||
// https://github.com/wkhtmltopdf/wkhtmltopdf/issues/4900
|
||||
if (request.getZoom() != 1.0) {
|
||||
String htmlContent = new String(Files.readAllBytes(tempInputFile));
|
||||
|
||||
String zoomStyle = "<style>body { zoom: " + request.getZoom() + "; }</style>";
|
||||
// Check for <head> tag, add style tag to associated tag
|
||||
if (htmlContent.contains("<head>")) {
|
||||
htmlContent = htmlContent.replace("<head>", "<head>" + zoomStyle);
|
||||
} else if (htmlContent.contains("<html>")) {
|
||||
// If no <head> tag, but <html> tag exists
|
||||
htmlContent = htmlContent.replace("<html>", "<html>" + zoomStyle);
|
||||
} else {
|
||||
// If neither <head> nor <html> tags exist
|
||||
htmlContent = zoomStyle + htmlContent;
|
||||
// Create a temporary CSS file
|
||||
File tempCssFile = Files.createTempFile("customStyle", ".css").toFile();
|
||||
try (FileWriter writer = new FileWriter(tempCssFile)) {
|
||||
// Write the CSS rule to the file
|
||||
writer.write("body { zoom: " + request.getZoom() + "; }");
|
||||
}
|
||||
// rewrite new html to file
|
||||
Files.write(tempInputFile, htmlContent.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
if (request.getPageWidth() != null) {
|
||||
command.add("--page-width");
|
||||
command.add(request.getPageWidth() + "cm");
|
||||
}
|
||||
|
||||
if (request.getPageHeight() != null) {
|
||||
command.add("--page-height");
|
||||
command.add(request.getPageHeight() + "cm");
|
||||
}
|
||||
|
||||
if (request.getMarginTop() != null) {
|
||||
command.add("--margin-top");
|
||||
command.add(request.getMarginTop() + "mm");
|
||||
}
|
||||
|
||||
// Repeat similar pattern for marginBottom, marginLeft, marginRight
|
||||
|
||||
if ("Yes".equalsIgnoreCase(request.getPrintBackground())) {
|
||||
command.add("--background");
|
||||
} else {
|
||||
command.add("--no-background");
|
||||
}
|
||||
|
||||
if ("Yes".equalsIgnoreCase(request.getDefaultHeader())) {
|
||||
command.add("--default-header");
|
||||
}
|
||||
|
||||
if ("print".equalsIgnoreCase(request.getCssMediaType())) {
|
||||
command.add("--print-media-type");
|
||||
} else if ("screen".equalsIgnoreCase(request.getCssMediaType())) {
|
||||
command.add("--no-print-media-type");
|
||||
command.add("--extra-css");
|
||||
command.add(tempCssFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
command.add(tempInputFile.toString());
|
||||
command.add(tempOutputFile.toString());
|
||||
ProcessExecutorResult returnCode;
|
||||
if (fileName.endsWith(".zip")) {
|
||||
|
||||
if (htmlFormatsInstalled) {
|
||||
// command.add(1, "--allow");
|
||||
// command.add(2, tempInputFile.getParent().toString());
|
||||
}
|
||||
returnCode =
|
||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.WEASYPRINT)
|
||||
.runCommandWithOutputHandling(
|
||||
command, tempInputFile.getParent().toFile());
|
||||
} else {
|
||||
|
||||
returnCode =
|
||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.WEASYPRINT)
|
||||
.runCommandWithOutputHandling(command);
|
||||
}
|
||||
returnCode =
|
||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.WEASYPRINT)
|
||||
.runCommandWithOutputHandling(command);
|
||||
|
||||
pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||
} catch (IOException e) {
|
||||
@@ -134,10 +81,6 @@ public class FileToPdf {
|
||||
// Clean up temporary files
|
||||
Files.delete(tempOutputFile);
|
||||
Files.delete(tempInputFile);
|
||||
|
||||
if (fileName.endsWith(".zip")) {
|
||||
GeneralUtils.deleteDirectory(tempInputFile.getParent());
|
||||
}
|
||||
}
|
||||
|
||||
return pdfBytes;
|
||||
@@ -145,7 +88,8 @@ public class FileToPdf {
|
||||
|
||||
private static Path unzipAndGetMainHtml(byte[] fileBytes) throws IOException {
|
||||
Path tempDirectory = Files.createTempDirectory("unzipped_");
|
||||
try (ZipInputStream zipIn = ZipSecurity.createHardenedInputStream(new ByteArrayInputStream(fileBytes))) {
|
||||
try (ZipInputStream zipIn =
|
||||
ZipSecurity.createHardenedInputStream(new ByteArrayInputStream(fileBytes))) {
|
||||
ZipEntry entry = zipIn.getNextEntry();
|
||||
while (entry != null) {
|
||||
Path filePath = tempDirectory.resolve(entry.getName());
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package stirling.software.SPDF.utils;
|
||||
|
||||
import io.github.pixee.security.HostValidator;
|
||||
import io.github.pixee.security.Urls;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -15,10 +12,14 @@ import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.HostValidator;
|
||||
import io.github.pixee.security.Urls;
|
||||
|
||||
public class GeneralUtils {
|
||||
|
||||
public static File convertMultipartFileToFile(MultipartFile multipartFile) throws IOException {
|
||||
@@ -59,7 +60,8 @@ public class GeneralUtils {
|
||||
|
||||
public static boolean isValidURL(String urlStr) {
|
||||
try {
|
||||
Urls.create(urlStr, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
|
||||
Urls.create(
|
||||
urlStr, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
|
||||
return true;
|
||||
} catch (MalformedURLException e) {
|
||||
return false;
|
||||
@@ -114,17 +116,36 @@ public class GeneralUtils {
|
||||
}
|
||||
|
||||
public static List<Integer> parsePageString(String pageOrder, int totalPages) {
|
||||
return parsePageList(pageOrder.split(","), totalPages);
|
||||
return parsePageString(pageOrder, totalPages, false);
|
||||
}
|
||||
|
||||
public static List<Integer> parsePageString(
|
||||
String pageOrder, int totalPages, boolean isOneBased) {
|
||||
if (pageOrder == null || pageOrder.isEmpty()) {
|
||||
return Collections.singletonList(1);
|
||||
}
|
||||
if (pageOrder.matches("\\d+")) {
|
||||
// Convert the single number string to an integer and return it in a list
|
||||
return Collections.singletonList(Integer.parseInt(pageOrder));
|
||||
}
|
||||
return parsePageList(pageOrder.split(","), totalPages, isOneBased);
|
||||
}
|
||||
|
||||
public static List<Integer> parsePageList(String[] pageOrderArr, int totalPages) {
|
||||
return parsePageList(pageOrderArr, totalPages, false);
|
||||
}
|
||||
|
||||
public static List<Integer> parsePageList(
|
||||
String[] pageOrderArr, int totalPages, boolean isOneBased) {
|
||||
List<Integer> newPageOrder = new ArrayList<>();
|
||||
|
||||
int adjustmentFactor = isOneBased ? 1 : 0;
|
||||
|
||||
// loop through the page order array
|
||||
for (String element : pageOrderArr) {
|
||||
if ("all".equalsIgnoreCase(element)) {
|
||||
for (int i = 0; i < totalPages; i++) {
|
||||
newPageOrder.add(i);
|
||||
newPageOrder.add(i + adjustmentFactor);
|
||||
}
|
||||
// As all pages are already added, no need to check further
|
||||
break;
|
||||
@@ -155,7 +176,7 @@ public class GeneralUtils {
|
||||
pageNum += constantExists ? constant : 0;
|
||||
|
||||
if (pageNum <= totalPages && pageNum > 0) {
|
||||
newPageOrder.add(pageNum - 1);
|
||||
newPageOrder.add(pageNum - adjustmentFactor);
|
||||
}
|
||||
}
|
||||
} else if (element.contains("-")) {
|
||||
@@ -170,11 +191,11 @@ public class GeneralUtils {
|
||||
// loop through the range of pages
|
||||
for (int j = start; j <= end; j++) {
|
||||
// print the current index
|
||||
newPageOrder.add(j - 1);
|
||||
newPageOrder.add(j - adjustmentFactor);
|
||||
}
|
||||
} else {
|
||||
// if the element is a single page
|
||||
newPageOrder.add(Integer.parseInt(element) - 1);
|
||||
newPageOrder.add(Integer.parseInt(element) - adjustmentFactor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.utils;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -21,6 +20,8 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
|
||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||
|
||||
public class PDFToFile {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.utils;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.RenderedImage;
|
||||
@@ -38,6 +37,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
|
||||
public class PdfUtils {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.utils;
|
||||
|
||||
import io.github.pixee.security.BoundedLineReader;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -17,6 +16,8 @@ import java.util.concurrent.TimeUnit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.github.pixee.security.BoundedLineReader;
|
||||
|
||||
public class ProcessExecutor {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProcessExecutor.class);
|
||||
@@ -110,7 +111,10 @@ public class ProcessExecutor {
|
||||
process.getErrorStream(),
|
||||
StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = BoundedLineReader.readLine(errorReader, 5_000_000)) != null) {
|
||||
while ((line =
|
||||
BoundedLineReader.readLine(
|
||||
errorReader, 5_000_000))
|
||||
!= null) {
|
||||
errorLines.add(line);
|
||||
if (liveUpdates) logger.info(line);
|
||||
}
|
||||
@@ -131,7 +135,10 @@ public class ProcessExecutor {
|
||||
process.getInputStream(),
|
||||
StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = BoundedLineReader.readLine(outputReader, 5_000_000)) != null) {
|
||||
while ((line =
|
||||
BoundedLineReader.readLine(
|
||||
outputReader, 5_000_000))
|
||||
!= null) {
|
||||
outputLines.add(line);
|
||||
if (liveUpdates) logger.info(line);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package stirling.software.SPDF.utils;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
@@ -13,6 +12,8 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
|
||||
public class WebResponseUtils {
|
||||
|
||||
public static ResponseEntity<byte[]> boasToWebResponse(
|
||||
|
||||
@@ -11,6 +11,7 @@ imgPrompt=Select Image(s)
|
||||
genericSubmit=Submit
|
||||
processTimeWarning=Warning: This process can take up to a minute depending on file-size
|
||||
pageOrderPrompt=Custom Page Order (Enter a comma-separated list of page numbers or Functions like 2n+1) :
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Go
|
||||
true=True
|
||||
false=False
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
language.direction=ltr
|
||||
|
||||
pdfPrompt=Selecteer PDF('s)
|
||||
multiPdfPrompt=Selecteer PDFs (2+)
|
||||
multiPdfDropPrompt=Selecteer (of sleep & zet neer) alle PDFs die je nodig hebt
|
||||
multiPdfPrompt=Selecteer PDF's (2+)
|
||||
multiPdfDropPrompt=Selecteer (of sleep & zet neer) alle PDF's die je nodig hebt
|
||||
imgPrompt=Selecteer afbeelding(en)
|
||||
genericSubmit=Indienen
|
||||
processTimeWarning=Waarschuwing: Dit proces kan tot een minuut duren afhankelijk van de bestandsgrootte
|
||||
@@ -65,7 +65,7 @@ pipeline.submitButton=Opslaan
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pijplijn onfiguratie
|
||||
pipelineOptions.header=Pijplijn configuratie
|
||||
pipelineOptions.pipelineNameLabel=Pijplijn naam
|
||||
pipelineOptions.saveSettings=Instellingen voor bewerking opslaan
|
||||
pipelineOptions.pipelineNamePrompt=Voer hier de naam van de pijplijn in
|
||||
@@ -217,7 +217,7 @@ home.removePassword.desc=Verwijder wachtwoordbeveiliging van je PDF-document.
|
||||
removePassword.tags=veilig,Decrypteren,beveiliging,wachtwoord verwijderen
|
||||
|
||||
home.compressPdfs.title=Comprimeren
|
||||
home.compressPdfs.desc=Comprimeer PDFs om hun bestandsgrootte te verkleinen.
|
||||
home.compressPdfs.desc=Comprimeer PDF's om hun bestandsgrootte te verkleinen.
|
||||
compressPdfs.tags=comprimeren,klein
|
||||
|
||||
|
||||
@@ -466,7 +466,7 @@ HTMLToPDF.header=HTML naar PDF
|
||||
HTMLToPDF.help=Accepteert HTML-bestanden en ZIP's die html/css/afbeeldingen etc. bevatten
|
||||
HTMLToPDF.submit=Converteren
|
||||
HTMLToPDF.credit=Gebruikt WeasyPrint
|
||||
HTMLToPDF.zoom=Zoom level for displaying the website.
|
||||
HTMLToPDF.zoom=Zoomniveau voor weergave van de website.
|
||||
HTMLToPDF.pageWidth=Breedte van de pagina in centimeters. (leeg voor standaard)
|
||||
HTMLToPDF.pageHeight=Hoogte van de pagina in centimeters. (leeg voor standaard)
|
||||
HTMLToPDF.marginTop=Marge bovenaan de pagina in millimeters. (leeg voor standaard)
|
||||
@@ -494,7 +494,7 @@ AddStampRequest.opacity=Transparantie
|
||||
AddStampRequest.position=Positie
|
||||
AddStampRequest.overrideX=X coördinaat overschrijven
|
||||
AddStampRequest.overrideY=Y coördinaat overschrijven
|
||||
AddStampRequest.customMargin=Aangepate marge
|
||||
AddStampRequest.customMargin=Aangepaste marge
|
||||
AddStampRequest.customColor=Aangepaste tekstkleur
|
||||
AddStampRequest.submit=Indienen
|
||||
|
||||
@@ -584,11 +584,11 @@ scalePages.submit=Indienen
|
||||
certSign.title=Certificaat ondertekening
|
||||
certSign.header=Onderteken een PDF met je certificaat (in ontwikkeling)
|
||||
certSign.selectPDF=Selecteer een PDF-bestand voor ondertekening:
|
||||
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=Let op: als het certificaattype hieronder niet staat, converteer het dan naar een Java Keystore (.jks) bestand met de keytool command line tool. Kies vervolgens de .jks bestandsoptie.
|
||||
certSign.selectKey=Selecteer je privésleutelbestand (PKCS#8 formaat, kan .pem of .der zijn):
|
||||
certSign.selectCert=Selecteer je certificaatbestand (X.509 formaat, kan .pem of .der zijn):
|
||||
certSign.selectP12=Selecteer je PKCS#12 Sleutelopslagbestand (.p12 of .pfx) (Optioneel, indien verstrekt, moet het je privésleutel en certificaat bevatten):
|
||||
certSign.selectJKS=Select Your Java Keystore File (.jks or .keystore):
|
||||
certSign.selectJKS=Selecteer je Java Keystore bestand (.jks of .keystore):
|
||||
certSign.certType=Certificaattype
|
||||
certSign.password=Voer je sleutelopslag of privésleutel wachtwoord in (indien van toepassing):
|
||||
certSign.showSig=Toon handtekening
|
||||
@@ -920,8 +920,8 @@ PDFToXML.submit=Converteren
|
||||
#PDFToCSV
|
||||
PDFToCSV.title=PDF naar CSV
|
||||
PDFToCSV.header=PDF naar CSV
|
||||
PDFToCSV.prompt=Choose page to extract table
|
||||
PDFToCSV.submit=Extract
|
||||
PDFToCSV.prompt=Kies pagina om tabel te extraheren
|
||||
PDFToCSV.submit=Extraheren
|
||||
|
||||
#split-by-size-or-count
|
||||
split-by-size-or-count.header=PDF splitsen op grootte of aantal
|
||||
@@ -961,11 +961,11 @@ split-by-sections.submit=PDF splitsen
|
||||
|
||||
|
||||
#licenses
|
||||
licenses.nav=Licensies
|
||||
licenses.title=Licensies van derden
|
||||
licenses.header=Licensies van derden
|
||||
licenses.nav=Licenties
|
||||
licenses.title=Licenties van derden
|
||||
licenses.header=Licenties van derden
|
||||
licenses.module=Module
|
||||
licenses.version=Versie
|
||||
licenses.license=Licensie
|
||||
licenses.license=Licentie
|
||||
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@ system:
|
||||
googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow
|
||||
enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes)
|
||||
customApplications:
|
||||
installBookFormats: false # Installs Calibre for book format conversion (For non docker it must be manually downloaded but will need to be true to show in UI)
|
||||
installAdvancedHtmlToPDF: false # DO NOT USE EXTERNALLY, NOT SAFE! Install wkHtmlToPDF (For non docker it must be manually downloaded but will need to be true to show in UI)
|
||||
bookAndHtmlFormatsInstalled: false # Installs Calibre for book format conversion (For non docker it must be manually downloaded but will need to be true to show in UI)
|
||||
|
||||
#ui:
|
||||
# appName: exampleAppName # Application's visible name
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 3.8 KiB |
@@ -2,8 +2,8 @@
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<TileColor>#2d89ef</TileColor>
|
||||
<square150x150logo src="/mstile-150x150.png?v=2"/>
|
||||
<TileColor>#00aba9</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 829 B |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 8.7 KiB |
@@ -1,298 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
width="99.537987mm"
|
||||
height="95.209366mm"
|
||||
viewBox="0 0 99.537987 95.209366"
|
||||
version="1.1"
|
||||
id="svg745"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 512 512"
|
||||
style="enable-background:new 0 0 512 512;"
|
||||
xml:space="preserve"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="stirling-transparent.svg"
|
||||
inkscape:export-filename="stirling.png"
|
||||
inkscape:export-xdpi="80"
|
||||
inkscape:export-ydpi="80"
|
||||
sodipodi:docname="favicon.svg"
|
||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||
inkscape:export-filename="favicon.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview747"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.914906"
|
||||
inkscape:cx="175.42786"
|
||||
inkscape:cy="510.43495"
|
||||
inkscape:window-width="2256"
|
||||
inkscape:window-height="1428"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg745" /><defs
|
||||
id="defs742"><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient72198"><stop
|
||||
style="stop-color:#ccd6d7;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop72194" /><stop
|
||||
style="stop-color:#0f3a3f;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop72196" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient71928"><stop
|
||||
style="stop-color:#4b0005;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop71924" /><stop
|
||||
style="stop-color:#8f000c;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop71926" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient71920"><stop
|
||||
style="stop-color:#4b0005;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop71916" /><stop
|
||||
style="stop-color:#8f000c;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop71918" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient69598"><stop
|
||||
style="stop-color:#6a0007;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop69594" /><stop
|
||||
style="stop-color:#b8000f;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop69596" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient46361"><stop
|
||||
style="stop-color:#f7f6f8;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop46359" /><stop
|
||||
style="stop-color:#b7b7b5;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop46357" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient40554"><stop
|
||||
style="stop-color:#f4f2f4;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop40550" /><stop
|
||||
style="stop-color:#57767b;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop40552" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient39095"><stop
|
||||
style="stop-color:#285459;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop39093" /><stop
|
||||
style="stop-color:#a6b6af;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop39091" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient36672"><stop
|
||||
style="stop-color:#da453f;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop36668" /><stop
|
||||
style="stop-color:#a60008;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop36670" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient19524"><stop
|
||||
style="stop-color:#3a4b4f;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop19522" /><stop
|
||||
style="stop-color:#617979;stop-opacity:0.97461927;"
|
||||
offset="1"
|
||||
id="stop19520" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient17996"><stop
|
||||
style="stop-color:#401016;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop17994" /><stop
|
||||
style="stop-color:#761f19;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop17992" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient15569"><stop
|
||||
style="stop-color:#8ea8ad;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop15565" /><stop
|
||||
style="stop-color:#e9e7eb;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop15567" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient15557"><stop
|
||||
style="stop-color:#9b0e11;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop15553" /><stop
|
||||
style="stop-color:#370707;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop15555" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient15557"
|
||||
id="linearGradient15559"
|
||||
x1="120.06672"
|
||||
y1="63.25761"
|
||||
x2="135.16347"
|
||||
y2="78.078682"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient15569"
|
||||
id="linearGradient15571"
|
||||
x1="127.97037"
|
||||
y1="101.66144"
|
||||
x2="133.88971"
|
||||
y2="104.77026"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient17996"
|
||||
id="linearGradient17998"
|
||||
x1="117.9284"
|
||||
y1="86.055084"
|
||||
x2="130.67392"
|
||||
y2="76.945541"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient19524"
|
||||
id="linearGradient19528"
|
||||
x1="130.98172"
|
||||
y1="82.402977"
|
||||
x2="135.72115"
|
||||
y2="86.45166"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient36672"
|
||||
id="linearGradient36674"
|
||||
x1="63.797714"
|
||||
y1="74.81752"
|
||||
x2="96.636673"
|
||||
y2="120.29293"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient39095"
|
||||
id="linearGradient39097"
|
||||
x1="120.54506"
|
||||
y1="124.76902"
|
||||
x2="128.04152"
|
||||
y2="126.0704"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient40554"
|
||||
id="linearGradient40556"
|
||||
x1="113.84585"
|
||||
y1="114.04285"
|
||||
x2="119.65858"
|
||||
y2="128.50244"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient46361"
|
||||
id="linearGradient46363"
|
||||
x1="73.993439"
|
||||
y1="114.13906"
|
||||
x2="94.845322"
|
||||
y2="71.247383"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient69598"
|
||||
id="linearGradient69600"
|
||||
x1="95.854446"
|
||||
y1="114.66749"
|
||||
x2="103.77842"
|
||||
y2="120.1887"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient71920"
|
||||
id="linearGradient71922"
|
||||
x1="98.580376"
|
||||
y1="87.186958"
|
||||
x2="118.09738"
|
||||
y2="101.19449"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient71928"
|
||||
id="linearGradient71930"
|
||||
x1="78.278267"
|
||||
y1="97.433273"
|
||||
x2="92.313202"
|
||||
y2="104.33479"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient72198"
|
||||
id="linearGradient72200"
|
||||
x1="125.76636"
|
||||
y1="138.46817"
|
||||
x2="123.3327"
|
||||
y2="126.03291"
|
||||
gradientUnits="userSpaceOnUse" /></defs><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer5"
|
||||
inkscape:label="shadow"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true"
|
||||
transform="translate(-51.420144,-44.470286)"><path
|
||||
style="display:inline;fill:url(#linearGradient72200);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 84.146049,134.73858 c 0,0 11.721038,2.48294 17.938661,2.91673 6.21763,0.43378 14.75251,0.59994 22.41237,-0.43379 8.01008,-1.081 13.19907,-2.22733 14.50043,-2.66112 1.30136,-0.43379 4.00784,-1.24297 4.15244,-2.25514 0.1446,-1.01217 -3.4703,-2.74733 -6.21763,-3.32571 -2.74732,-0.57838 -12.72444,-1.44596 -14.89337,-1.44596 -2.16894,0 -37.892901,7.20499 -37.892901,7.20499 z"
|
||||
id="path72192"
|
||||
sodipodi:nodetypes="cssssssc" /></g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Origami"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true"
|
||||
transform="translate(-51.420144,-44.470286)"><path
|
||||
style="display:inline;fill:url(#linearGradient40556);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 84.460552,134.86721 35.165798,-6.85679 16.15467,-42.7383 z"
|
||||
id="path960"
|
||||
sodipodi:nodetypes="cccc" /><path
|
||||
style="fill:url(#linearGradient15571);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 135.71493,85.428056 0.3984,45.049024 -9.66213,-20.46173 z"
|
||||
id="path964"
|
||||
sodipodi:nodetypes="cccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient39097);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 119.60518,128.00293 16.5337,2.48693 -9.68769,-20.5512 z"
|
||||
id="path966"
|
||||
sodipodi:nodetypes="cccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient15559);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 118.42209,57.022622 12.70423,-2.766809 -0.0785,25.087175 -12.43878,-13.376518 z"
|
||||
id="path968"
|
||||
sodipodi:nodetypes="ccccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient19528);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 135.72114,85.386768 -4.84219,-6.459493 0.0305,11.126604 z"
|
||||
id="path970"
|
||||
sodipodi:nodetypes="cccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient17998);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 119.10273,65.682415 11.96883,13.44935 -0.0899,10.819868 -11.88577,11.430427 z"
|
||||
id="path972"
|
||||
sodipodi:nodetypes="ccccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient36674);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 62.145635,130.15618 62.043392,65.435258 c 0,0 0.179321,-2.778132 1.89516,-4.036097 1.874923,-1.374597 4.341768,-1.894096 4.341768,-1.894096 l 50.91788,-11.349167 -0.0113,53.144272 -34.733274,33.56547 z"
|
||||
id="path958"
|
||||
sodipodi:nodetypes="ccsccccc" /></g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Letter"
|
||||
style="display:inline"
|
||||
sodipodi:insensitive="true"
|
||||
transform="translate(-51.420144,-44.470286)"><path
|
||||
style="display:inline;fill:url(#linearGradient69600);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 94.780881,91.406803 16.870379,17.074877 -23.723345,23.00249 -18.122131,-17.99816 5.497473,-2.80607 18.404054,-0.0511 2.35163,-8.23071 z"
|
||||
id="path54894"
|
||||
sodipodi:nodetypes="cccccccc" /><path
|
||||
style="display:inline;fill:url(#linearGradient71930);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 72.440405,92.224764 16.15467,15.745686 4.089788,-6.79927 z"
|
||||
id="path54892" /><path
|
||||
style="display:inline;fill:url(#linearGradient71922);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 95.138739,84.965385 1.124691,-14.109776 22.92453,22.286787 0.008,8.164604 -3.28863,3.16649 z"
|
||||
id="path54890"
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:label="path54890" /><path
|
||||
style="display:inline;fill:url(#linearGradient46363);fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 95.138739,84.965385 h 1.226936 l -0.05112,-14.109776 c 0,0 -5.776827,-3.220709 -12.167126,-2.40275 -6.390296,0.817957 -8.151582,2.1248 -10.58233,4.396523 -1.90229,1.777838 -2.913974,3.527446 -3.987546,7.157132 -0.512646,1.733226 -0.281963,5.988892 0.613471,8.537436 0.664591,1.891528 2.453873,4.294281 4.958868,6.134686 2.662335,1.956002 8.281825,3.527443 8.281825,3.527443 0,0 5.134614,1.887351 5.572338,4.294281 0.308137,1.69437 -0.102243,3.22071 -1.635914,4.95887 -1.258314,1.42609 -3.62969,1.99377 -6.288054,1.07357 -2.658364,-0.92021 -6.139514,-3.85065 -7.106009,-4.90775 -0.817958,-0.89464 -2.820665,-3.06173 -2.890231,-4.294021 -0.01209,-0.214205 -1.229505,-0.0963 -1.229505,-0.0963 l -0.0723,14.256941 5.879073,2.24938 c 0,0 5.214483,1.78929 8.946415,1.43143 3.731934,-0.35786 7.617235,-0.51122 11.604778,-5.16336 3.987542,-4.65213 3.680812,-12.831715 2.147141,-15.899056 -1.533673,-3.067344 -3.561212,-6.138812 -10.480087,-8.281826 -5.776829,-1.789283 -7.872846,-3.01622 -8.128458,-4.396524 -0.255611,-1.380305 0.0091,-4.253646 2.760607,-5.214481 3.220711,-1.124693 5.623462,-0.05112 7.05489,1.12469 1.431425,1.175817 5.572339,5.623462 5.572339,5.623462 z"
|
||||
id="path46355"
|
||||
sodipodi:nodetypes="cccssssscssssscccssssssscc" /></g></svg>
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs173">
|
||||
|
||||
|
||||
<linearGradient
|
||||
id="XMLID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="304.496"
|
||||
y1="422.9102"
|
||||
x2="316.036"
|
||||
y2="326.2626">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#DCF1F3"
|
||||
id="stop156" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#C2C2C9"
|
||||
id="stop158" />
|
||||
</linearGradient>
|
||||
|
||||
</defs><sodipodi:namedview
|
||||
id="namedview171"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="219.91021"
|
||||
inkscape:cy="232.63813"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2054"
|
||||
inkscape:window-x="2869"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="XMLID_4_" />
|
||||
<style
|
||||
type="text/css"
|
||||
id="style150">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#C02223;}
|
||||
.st2{fill:#882425;}
|
||||
.st3{fill:url(#XMLID_5_);}
|
||||
.st4{fill:url(#XMLID_7_);}
|
||||
</style>
|
||||
|
||||
<g
|
||||
id="XMLID_4_">
|
||||
<path
|
||||
id="XMLID_131_"
|
||||
class="st1"
|
||||
d="M 347.01402,14.355825 98.978019,69.02261 C 73.825483,74.547445 55.942464,96.792175 55.942464,122.52628 v 315.06096 c 0,22.39012 16.719895,41.14548 38.819234,43.76251 L 224.8861,498.36042 339.48636,384.26465 455.76603,265.15425 453.73057,84.870162 C 453.43979,62.916214 433.08513,46.632491 411.71274,51.284984 l -28.78729,6.251786 0.14539,-13.666697 C 383.36162,24.678542 365.62399,10.284894 347.01402,14.355825 Z"
|
||||
sodipodi:nodetypes="ccssccccccccc"
|
||||
style="stroke-width:1.45391" /><path
|
||||
id="XMLID_117_"
|
||||
class="st2"
|
||||
d="m 383.21622,57.53677 v 285.8375 L 456.05681,265.00885 454.02135,78.763767 C 453.87595,59.863016 436.28372,45.905539 417.81914,49.97647 Z"
|
||||
style="stroke-width:1.45391" /><polygon
|
||||
id="XMLID_18_"
|
||||
class="st3"
|
||||
points="234.7,422.6 368.5,387.7 393.5,262.2 "
|
||||
style="fill:url(#XMLID_5_)"
|
||||
transform="matrix(1.4556308,0,0,1.4548265,-116.73161,-116.45231)" />
|
||||
<linearGradient
|
||||
id="XMLID_7_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="223.0838"
|
||||
y1="372.7559"
|
||||
x2="241.4174"
|
||||
y2="114.557"
|
||||
gradientTransform="matrix(1.4539039,0,0,1.4539039,-116.19976,-116.20474)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#DCF1F3"
|
||||
id="stop163" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#C2C2C9"
|
||||
id="stop165" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="XMLID_6_"
|
||||
class="st4"
|
||||
d="m 282.89686,214.84917 c 0,0 -22.24473,-28.93269 -38.67384,-36.78377 -10.46811,-4.94327 -26.02489,-6.83335 -38.23768,-0.72695 -18.02841,9.0142 -19.91848,34.31213 -3.34397,44.34406 3.92553,2.47165 9.15959,4.50711 15.99294,6.10641 36.63838,8.43264 97.12077,25.87949 89.70587,96.10304 0,0 -4.21633,65.86185 -73.56753,73.42215 -12.2128,1.30851 -24.57098,0.43617 -36.493,-2.32625 -16.42911,-3.63476 -45.50719,-11.04967 -59.75545,-19.91849 l -2.61703,-75.16682 h 6.97875 c 0,0 13.81208,33.43978 53.06749,49.57812 7.26952,2.90781 15.26599,4.07093 22.97168,2.90781 9.74116,-1.45391 21.22699,-6.68796 25.87949,-22.53551 0,0 7.85108,-23.11707 -32.85823,-35.76604 -32.56744,-10.17733 -63.24481,-20.64543 -75.89378,-54.95757 -5.961,-16.28371 -6.97874,-34.31212 -2.90781,-51.61358 5.37944,-22.53551 20.79082,-54.23062 64.40794,-67.89732 0,0 57.28381,-15.55677 96.53922,5.52484 l -1.74468,89.70587 z"
|
||||
style="fill:url(#XMLID_7_);stroke-width:1.45391" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -14,13 +14,16 @@ function initializeGame() {
|
||||
const highScoreElement = document.getElementById('high-score');
|
||||
|
||||
let pdfSize = gameContainer.clientWidth * 0.0625; // 5% of container width
|
||||
let projectileWidth = gameContainer.clientWidth * 0.00625; // 0.5% of container width
|
||||
let projectileWidth = gameContainer.clientWidth * 0.00625;// 0.00625; // 0.5% of container width
|
||||
let projectileHeight = gameContainer.clientHeight * 0.01667; // 1% of container height
|
||||
|
||||
let paused = false;
|
||||
|
||||
const fireRate = 200; // Time between shots in milliseconds
|
||||
let lastProjectileTime = 0;
|
||||
let lives = 3;
|
||||
|
||||
|
||||
let highScore = localStorage.getItem('highScore') ? parseInt(localStorage.getItem('highScore')) : 0;
|
||||
updateHighScore();
|
||||
|
||||
@@ -31,7 +34,7 @@ function initializeGame() {
|
||||
const projectiles = [];
|
||||
let score = 0;
|
||||
let level = 1;
|
||||
let pdfSpeed = 1;
|
||||
let pdfSpeed = 0.5;
|
||||
let gameOver = false;
|
||||
|
||||
function handleKeys() {
|
||||
@@ -119,7 +122,7 @@ function initializeGame() {
|
||||
|
||||
for (let pdfIndex = 0; pdfIndex < pdfs.length; pdfIndex++) {
|
||||
const pdf = pdfs[pdfIndex];
|
||||
const pdfY = parseInt(pdf.style.top) + pdfSpeed;
|
||||
const pdfY = parseFloat(pdf.style.top) + pdfSpeed;
|
||||
if (pdfY + 50 > gameContainer.clientHeight) {
|
||||
gameContainer.removeChild(pdf);
|
||||
pdfs.splice(pdfIndex, 1);
|
||||
@@ -218,7 +221,7 @@ function initializeGame() {
|
||||
if (newLevel > level) {
|
||||
level = newLevel;
|
||||
levelElement.textContent = 'Level: ' + level;
|
||||
pdfSpeed += 1;
|
||||
pdfSpeed += 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,6 +252,10 @@ function initializeGame() {
|
||||
|
||||
let spawnPdfTimeout;
|
||||
|
||||
const BASE_SPAWN_INTERVAL_MS = 1250; // milliseconds before a new enemy spawns
|
||||
const LEVEL_INCREASE_FACTOR_MS = 0; // milliseconds to decrease the spawn interval per level
|
||||
const MAX_SPAWN_RATE_REDUCTION_MS = 800; // Max milliseconds from the base spawn interval
|
||||
|
||||
function spawnPdfInterval() {
|
||||
console.log("spawnPdfInterval");
|
||||
if (gameOver || paused) {
|
||||
@@ -258,7 +265,9 @@ function initializeGame() {
|
||||
}
|
||||
console.log("spawnPdfInterval 3");
|
||||
spawnPdf();
|
||||
spawnPdfTimeout = setTimeout(spawnPdfInterval, 1000 - level * 50);
|
||||
let spawnRateReduction = Math.min(level * LEVEL_INCREASE_FACTOR_MS, MAX_SPAWN_RATE_REDUCTION_MS);
|
||||
let spawnRate = BASE_SPAWN_INTERVAL_MS - spawnRateReduction;
|
||||
spawnPdfTimeout = setTimeout(spawnPdfInterval, spawnRate);
|
||||
}
|
||||
|
||||
updatePlayerPosition();
|
||||
|
||||
BIN
src/main/resources/static/mstile-144x144.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 3.2 KiB |
BIN
src/main/resources/static/mstile-310x150.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src/main/resources/static/mstile-310x310.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
src/main/resources/static/mstile-70x70.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
@@ -2,40 +2,30 @@
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="752.000000pt" height="752.000000pt" viewBox="0 0 752.000000 752.000000"
|
||||
width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,752.000000) scale(0.100000,-0.100000)"
|
||||
<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M5025 7049 c-87 -21 -1141 -257 -2770 -620 -566 -126 -1057 -239
|
||||
-1090 -250 -153 -56 -253 -125 -297 -206 -62 -113 -58 67 -58 -2629 l0 -2462
|
||||
22 -5 c73 -19 1640 -347 1655 -347 9 0 58 39 107 88 596 575 1106 1069 1611
|
||||
1556 336 324 725 700 865 836 140 135 383 369 540 520 157 151 390 377 518
|
||||
502 l233 228 -23 33 c-12 17 -89 122 -170 231 l-148 200 0 944 c0 894 -1 943
|
||||
-17 938 -40 -11 -853 -186 -868 -186 -13 0 -15 38 -15 325 0 179 -3 325 -7
|
||||
324 -5 -1 -44 -10 -88 -20z m-2205 -1513 c167 -23 343 -73 504 -145 l66 -30 0
|
||||
-536 0 -535 -40 0 c-40 0 -46 6 -263 224 -211 212 -226 226 -307 265 -142 68
|
||||
-274 75 -427 21 -141 -49 -213 -161 -213 -329 0 -89 16 -124 82 -172 91 -66
|
||||
206 -115 499 -212 228 -76 340 -126 458 -204 157 -105 282 -253 366 -436 59
|
||||
-128 70 -203 69 -452 -1 -213 -2 -224 -31 -337 -33 -123 -89 -255 -144 -335
|
||||
-43 -63 -169 -194 -240 -248 -172 -134 -388 -199 -705 -212 -260 -11 -473 34
|
||||
-858 179 l-246 93 3 540 2 540 43 3 c34 3 43 0 48 -15 48 -159 263 -392 514
|
||||
-560 159 -107 273 -152 401 -160 154 -10 269 42 353 160 74 104 102 196 90
|
||||
295 -18 145 -192 275 -511 381 -375 125 -541 216 -706 386 -198 203 -273 411
|
||||
-271 760 l0 170 38 110 c77 223 147 338 285 468 158 148 283 219 478 268 252
|
||||
64 465 81 663 55z"/>
|
||||
<path d="M5633 2297 c-267 -688 -370 -952 -393 -1002 l-27 -60 -114 -44 c-63
|
||||
-24 -127 -50 -144 -57 -16 -7 -104 -43 -195 -79 -91 -36 -174 -70 -185 -75
|
||||
-11 -5 -46 -19 -77 -30 -32 -12 -58 -26 -58 -31 0 -6 -4 -8 -10 -4 -5 3 -17 1
|
||||
-27 -4 -25 -14 -169 -44 -1248 -256 -324 -64 -599 -119 -610 -122 -17 -5 -15
|
||||
-8 12 -15 63 -17 633 -117 803 -142 293 -42 276 -42 471 -3 96 20 226 45 289
|
||||
57 63 12 282 55 485 95 204 40 422 83 485 95 63 12 237 46 385 75 231 46 390
|
||||
77 765 149 l65 13 -50 11 c-27 6 -192 34 -365 62 -173 28 -331 54 -350 59 -41
|
||||
9 -41 -12 1 226 30 175 61 355 124 720 20 116 42 235 49 266 12 53 11 61 -12
|
||||
118 -13 33 -27 61 -31 61 -3 0 -20 -37 -38 -83z"/>
|
||||
<path d="M6404 928 c4 -23 8 -44 10 -45 2 -2 44 4 94 14 51 9 89 20 84 24 -8
|
||||
9 -158 49 -180 49 -11 0 -13 -9 -8 -42z"/>
|
||||
<path d="M4340 6716 c-228 -51 -910 -202 -1515 -336 -1479 -326 -1522 -335
|
||||
-1587 -360 -155 -58 -315 -206 -391 -363 -83 -170 -77 40 -77 -2484 0 -1985 2
|
||||
-2256 15 -2307 53 -204 228 -378 431 -430 32 -8 464 -67 959 -132 l900 -117
|
||||
659 664 c362 365 1074 1083 1581 1595 l923 931 -4 84 c-2 46 -9 622 -14 1279
|
||||
-6 657 -15 1219 -21 1249 -29 169 -167 304 -337 331 -74 12 -116 6 -397 -55
|
||||
-112 -25 -208 -45 -214 -45 -7 0 -11 33 -11 98 0 54 -5 125 -11 158 -24 129
|
||||
-106 237 -225 295 -59 29 -78 33 -158 35 -83 3 -128 -6 -506 -90z m-741 -1297
|
||||
c108 -15 244 -53 336 -91 l80 -34 -4 -314 c-2 -173 -7 -450 -10 -615 l-6 -300
|
||||
-61 -3 -61 -3 -74 88 c-298 355 -496 483 -747 483 -74 0 -202 -32 -257 -65
|
||||
-106 -61 -177 -184 -178 -305 0 -82 15 -135 56 -197 62 -92 157 -138 437 -209
|
||||
393 -99 639 -221 826 -408 136 -137 206 -259 255 -442 30 -113 37 -363 15
|
||||
-494 -85 -488 -398 -821 -866 -921 -87 -19 -136 -23 -285 -23 -165 0 -193 3
|
||||
-335 33 -280 59 -585 154 -746 231 l-80 39 -12 373 c-7 205 -15 437 -19 516
|
||||
l-6 142 51 0 c32 0 52 -4 52 -11 0 -24 99 -176 172 -264 125 -151 278 -272
|
||||
455 -359 147 -73 181 -81 328 -81 127 0 132 1 202 34 137 64 236 205 236 337
|
||||
0 131 -96 257 -262 343 -45 23 -180 75 -300 116 -333 112 -496 191 -646 312
|
||||
-321 260 -442 767 -290 1219 110 330 325 579 633 733 144 73 364 127 613 151
|
||||
113 10 395 5 498 -11z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -3,12 +3,12 @@
|
||||
"short_name": "Stirling PDF",
|
||||
"icons": [
|
||||
{
|
||||
"src": "android-chrome-192x192.png",
|
||||
"src": "/android-chrome-192x192.png?v=2",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "android-chrome-512x512.png",
|
||||
"src": "/android-chrome-512x512.png?v=2",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
|
||||
@@ -20,63 +20,6 @@
|
||||
<label for="zoom" th:text="#{HTMLToPDF.zoom}" class="form-label"></label>
|
||||
<input type="number" step="0.1" class="form-control" id="zoom" name="zoom" value="1" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="pageWidth" th:text="#{HTMLToPDF.pageWidth}" class="form-label"></label>
|
||||
<input type="number" class="form-control" id="pageWidth" name="pageWidth" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="pageHeight" th:text="#{HTMLToPDF.pageHeight}" class="form-label"></label>
|
||||
<input type="number" class="form-control" id="pageHeight" name="pageHeight" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="marginTop" th:text="#{HTMLToPDF.marginTop}" class="form-label"></label>
|
||||
<input type="number" class="form-control" id="marginTop" name="marginTop" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="marginBottom" th:text="#{HTMLToPDF.marginBottom}" class="form-label"></label>
|
||||
<input type="number" class="form-control" id="marginBottom" name="marginBottom" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="marginLeft" th:text="#{HTMLToPDF.marginLeft}" class="form-label"></label>
|
||||
<input type="number" class="form-control" id="marginLeft" name="marginLeft" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="marginRight" th:text="#{HTMLToPDF.marginRight}" class="form-label"></label>
|
||||
<input type="number" class="form-control" id="marginRight" name="marginRight" />
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label th:text="#{HTMLToPDF.printBackground}" class="form-label"></label>
|
||||
<select class="form-select" name="printBackground">
|
||||
<option value="Yes" th:text="#{yes}">Yes</option>
|
||||
<option value="No" th:text="#{no}">No</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label th:text="#{HTMLToPDF.defaultHeader}" class="form-label"></label>
|
||||
<select class="form-select" name="defaultHeader">
|
||||
<option value="No" th:text="#{no}">No</option>
|
||||
<option value="Yes" th:text="#{yes}">Yes</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-3">
|
||||
<label th:text="#{HTMLToPDF.cssMediaType}" class="form-label"></label>
|
||||
<select class="form-select" name="cssMediaType">
|
||||
<option value="screen" th:text="#{HTMLToPDF.screen}">Screen</option>
|
||||
<option value="none" th:text="#{HTMLToPDF.none}">None</option>
|
||||
<option value="print" th:text="#{HTMLToPDF.print}">Print</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<br>
|
||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{HTMLToPDF.submit}"></button>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<div class="mb-3">
|
||||
<label th:text="#{PDFToText.selectText.1}"></label>
|
||||
<select class="form-control" name="outputFormat">
|
||||
<option value="rtf">RTF</option>
|
||||
<option value="txt">TXT</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -11,20 +11,16 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="shortcut icon" href="favicon.svg">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
|
||||
<link rel="manifest" href="site.webmanifest">
|
||||
<link rel="mask-icon" href="safari-pinned-tab.svg" color="#ca2b2a">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=2">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png?v=2">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png?v=2">
|
||||
<link rel="manifest" href="/site.webmanifest?v=2">
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg?v=2" color="#ca2b2a">
|
||||
<link rel="shortcut icon" href="/favicon.ico?v=2">
|
||||
<meta name="apple-mobile-web-app-title" content="Stirling PDF">
|
||||
<meta name="application-name" content="Stirling PDF">
|
||||
<meta name="msapplication-TileColor" content="#00aba9">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="js/thirdParty/jquery.min.js"></script>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="container ">
|
||||
|
||||
<a class="navbar-brand" href="#" th:href="@{/}" >
|
||||
<img class="main-icon" src="favicon.svg" alt="icon">
|
||||
<img class="main-icon" src="favicon.svg?v=2" alt="icon">
|
||||
<span class="icon-text" th:text="${@navBarText}"></span>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -260,7 +260,7 @@ function handleDropdownItemClick(event) {
|
||||
<span th:text="#{changedCredsMessage}">Default message if not found</span>
|
||||
</div>
|
||||
<form th:action="@{login}" method="post">
|
||||
<img class="mb-4" src="favicon.svg" alt="" width="144" height="144">
|
||||
<img class="mb-4" src="favicon.svg?v=2" alt="" width="144" height="144">
|
||||
<h1 class="h1 mb-3 fw-normal" th:text="${@appName}">Stirling-PDF</h1>
|
||||
<h2 class="h5 mb-3 fw-normal" th:text="#{login.signinTitle}">Please sign in</h2>
|
||||
|
||||
|
||||