Compare commits
31 Commits
2299-featu
...
pre-commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02c75aea95 | ||
|
|
ee6fbdd61f | ||
|
|
a5da7fc2c3 | ||
|
|
1f92318df4 | ||
|
|
9df5e2aca0 | ||
|
|
6aad45fcec | ||
|
|
ec5018cc80 | ||
|
|
2404ceb46e | ||
|
|
f23a2d508f | ||
|
|
f5ca02df1d | ||
|
|
1e29cf43fb | ||
|
|
ebfe00717d | ||
|
|
063a7244a3 | ||
|
|
7b9e52dec6 | ||
|
|
296dbc5dea | ||
|
|
f6654a06d9 | ||
|
|
219adb99ec | ||
|
|
23a7b11a74 | ||
|
|
6ac804e994 | ||
|
|
09ff207888 | ||
|
|
880ca6af7f | ||
|
|
3797a6827c | ||
|
|
0f5d95661c | ||
|
|
d5aea7f0b6 | ||
|
|
0412263d01 | ||
|
|
d3d9158641 | ||
|
|
c785fb20d1 | ||
|
|
ac09831654 | ||
|
|
487a82eb65 | ||
|
|
0f5db746c7 | ||
|
|
139faf4eba |
2
.github/workflows/PR-Demo-Comment.yml
vendored
2
.github/workflows/PR-Demo-Comment.yml
vendored
@@ -121,7 +121,7 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKER_HUB_API }}
|
password: ${{ secrets.DOCKER_HUB_API }}
|
||||||
|
|
||||||
- name: Build and push PR-specific image
|
- name: Build and push PR-specific image
|
||||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
|
|||||||
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -49,7 +49,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload Test Reports
|
- name: Upload Test Reports
|
||||||
if: always()
|
if: always()
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
name: test-reports-jdk-${{ matrix.jdk-version }}
|
name: test-reports-jdk-${{ matrix.jdk-version }}
|
||||||
path: |
|
path: |
|
||||||
@@ -80,7 +80,7 @@ jobs:
|
|||||||
|
|
||||||
- name: FAILED - check the licenses for compatibility
|
- name: FAILED - check the licenses for compatibility
|
||||||
if: failure()
|
if: failure()
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
name: dependencies-without-allowed-license.json
|
name: dependencies-without-allowed-license.json
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
4
.github/workflows/licenses-update.yml
vendored
4
.github/workflows/licenses-update.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@67e27a7eb7db372a1c61a7f9bdab8699e9ee57f7 # v1.11.3
|
uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.GH_APP_ID }}
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
@@ -45,7 +45,7 @@ jobs:
|
|||||||
|
|
||||||
- name: FAILED - check the licenses for compatibility
|
- name: FAILED - check the licenses for compatibility
|
||||||
if: failure()
|
if: failure()
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
name: dependencies-without-allowed-license.json
|
name: dependencies-without-allowed-license.json
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
10
.github/workflows/multiOSReleases.yml
vendored
10
.github/workflows/multiOSReleases.yml
vendored
@@ -80,7 +80,7 @@ jobs:
|
|||||||
mv ./build/libs/Stirling-PDF-${{ needs.read_versions.outputs.version }}.jar ./binaries/Stirling-PDF${{ matrix.file_suffix }}.jar
|
mv ./build/libs/Stirling-PDF-${{ needs.read_versions.outputs.version }}.jar ./binaries/Stirling-PDF${{ matrix.file_suffix }}.jar
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
@@ -114,7 +114,7 @@ jobs:
|
|||||||
run: ls -R
|
run: ls -R
|
||||||
|
|
||||||
- name: Upload signed artifacts
|
- name: Upload signed artifacts
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
@@ -188,7 +188,7 @@ jobs:
|
|||||||
run: ls -R ./binaries
|
run: ls -R ./binaries
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
@@ -224,7 +224,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Cosign
|
- name: Install Cosign
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
|
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
|
||||||
|
|
||||||
- name: Generate key pair
|
- name: Generate key pair
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
@@ -255,7 +255,7 @@ jobs:
|
|||||||
run: ls -R
|
run: ls -R
|
||||||
|
|
||||||
- name: Upload signed artifacts
|
- name: Upload signed artifacts
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|||||||
2
.github/workflows/pre_commit.yml
vendored
2
.github/workflows/pre_commit.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@67e27a7eb7db372a1c61a7f9bdab8699e9ee57f7 # v1.11.3
|
uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.GH_APP_ID }}
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
|
|||||||
8
.github/workflows/push-docker.yml
vendored
8
.github/workflows/push-docker.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install cosign
|
- name: Install cosign
|
||||||
if: github.ref == 'refs/heads/master'
|
if: github.ref == 'refs/heads/master'
|
||||||
uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
|
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
|
||||||
with:
|
with:
|
||||||
cosign-release: "v2.4.1"
|
cosign-release: "v2.4.1"
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push main Dockerfile
|
- name: Build and push main Dockerfile
|
||||||
id: build-push-regular
|
id: build-push-regular
|
||||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0
|
||||||
with:
|
with:
|
||||||
builder: ${{ steps.buildx.outputs.name }}
|
builder: ${{ steps.buildx.outputs.name }}
|
||||||
context: .
|
context: .
|
||||||
@@ -135,7 +135,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push Dockerfile-ultra-lite
|
- name: Build and push Dockerfile-ultra-lite
|
||||||
id: build-push-lite
|
id: build-push-lite
|
||||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0
|
||||||
if: github.ref != 'refs/heads/main'
|
if: github.ref != 'refs/heads/main'
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
@@ -166,7 +166,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push main Dockerfile fat
|
- name: Build and push main Dockerfile fat
|
||||||
id: build-push-fat
|
id: build-push-fat
|
||||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0
|
||||||
if: github.ref != 'refs/heads/main'
|
if: github.ref != 'refs/heads/main'
|
||||||
with:
|
with:
|
||||||
builder: ${{ steps.buildx.outputs.name }}
|
builder: ${{ steps.buildx.outputs.name }}
|
||||||
|
|||||||
6
.github/workflows/releaseArtifacts.yml
vendored
6
.github/workflows/releaseArtifacts.yml
vendored
@@ -63,7 +63,7 @@ jobs:
|
|||||||
ls -R ./build/launch4j
|
ls -R ./build/launch4j
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
name: binaries${{ matrix.file_suffix }}
|
name: binaries${{ matrix.file_suffix }}
|
||||||
path: |
|
path: |
|
||||||
@@ -95,7 +95,7 @@ jobs:
|
|||||||
run: ls -R
|
run: ls -R
|
||||||
|
|
||||||
- name: Install Cosign
|
- name: Install Cosign
|
||||||
uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
|
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
|
||||||
|
|
||||||
- name: Generate key pair
|
- name: Generate key pair
|
||||||
run: cosign generate-key-pair
|
run: cosign generate-key-pair
|
||||||
@@ -139,7 +139,7 @@ jobs:
|
|||||||
./launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe
|
./launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe
|
||||||
|
|
||||||
- name: Upload signed artifacts
|
- name: Upload signed artifacts
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
name: signed${{ matrix.file_suffix }}
|
name: signed${{ matrix.file_suffix }}
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
6
.github/workflows/scorecards.yml
vendored
6
.github/workflows/scorecards.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: "Run analysis"
|
- name: "Run analysis"
|
||||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
|
||||||
with:
|
with:
|
||||||
results_file: results.sarif
|
results_file: results.sarif
|
||||||
results_format: sarif
|
results_format: sarif
|
||||||
@@ -66,7 +66,7 @@ jobs:
|
|||||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||||
# format to the repository Actions tab.
|
# format to the repository Actions tab.
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
name: SARIF file
|
name: SARIF file
|
||||||
path: results.sarif
|
path: results.sarif
|
||||||
@@ -74,6 +74,6 @@ jobs:
|
|||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
|
uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|||||||
4
.github/workflows/sonarqube.yml
vendored
4
.github/workflows/sonarqube.yml
vendored
@@ -46,7 +46,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload Problems Report on Failure
|
- name: Upload Problems Report on Failure
|
||||||
if: failure()
|
if: failure()
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
name: gradle-problems-report
|
name: gradle-problems-report
|
||||||
path: build/reports/problems/problems-report.html
|
path: build/reports/problems/problems-report.html
|
||||||
@@ -54,7 +54,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload Sonar Logs on Failure
|
- name: Upload Sonar Logs on Failure
|
||||||
if: failure()
|
if: failure()
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||||
with:
|
with:
|
||||||
name: sonar-logs
|
name: sonar-logs
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
4
.github/workflows/sync_files.yml
vendored
4
.github/workflows/sync_files.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@67e27a7eb7db372a1c61a7f9bdab8699e9ee57f7 # v1.11.3
|
uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.GH_APP_ID }}
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
@@ -63,7 +63,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@67e27a7eb7db372a1c61a7f9bdab8699e9ee57f7 # v1.11.3
|
uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5
|
||||||
with:
|
with:
|
||||||
app-id: ${{ vars.GH_APP_ID }}
|
app-id: ${{ vars.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
|
|||||||
2
.github/workflows/testdriver.yml
vendored
2
.github/workflows/testdriver.yml
vendored
@@ -46,7 +46,7 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKER_HUB_API }}
|
password: ${{ secrets.DOCKER_HUB_API }}
|
||||||
|
|
||||||
- name: Build and push test image
|
- name: Build and push test image
|
||||||
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
|
uses: docker/build-push-action@0adf9959216b96bec444f325f1e493d4aa344497 # v6.14.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ COPY . .
|
|||||||
|
|
||||||
# Build the application with DOCKER_ENABLE_SECURITY=false
|
# Build the application with DOCKER_ENABLE_SECURITY=false
|
||||||
RUN DOCKER_ENABLE_SECURITY=true \
|
RUN DOCKER_ENABLE_SECURITY=true \
|
||||||
STIRLING_PDF_DESKTOP_UI=false \
|
STIRLING_PDF_DESKTOP_UI=false \
|
||||||
./gradlew clean build
|
./gradlew clean build
|
||||||
|
|
||||||
# Main stage
|
# Main stage
|
||||||
FROM alpine:3.21.3@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c
|
FROM alpine:3.21.3@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c
|
||||||
@@ -50,29 +50,29 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
|
|||||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
||||||
apk upgrade --no-cache -a && \
|
apk upgrade --no-cache -a && \
|
||||||
apk add --no-cache \
|
apk add --no-cache \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
tzdata \
|
tzdata \
|
||||||
tini \
|
tini \
|
||||||
bash \
|
bash \
|
||||||
curl \
|
curl \
|
||||||
shadow \
|
shadow \
|
||||||
su-exec \
|
su-exec \
|
||||||
openssl \
|
openssl \
|
||||||
openssl-dev \
|
openssl-dev \
|
||||||
openjdk21-jre \
|
openjdk21-jre \
|
||||||
# Doc conversion
|
# Doc conversion
|
||||||
gcompat \
|
gcompat \
|
||||||
libc6-compat \
|
libc6-compat \
|
||||||
libreoffice \
|
libreoffice \
|
||||||
# pdftohtml
|
# pdftohtml
|
||||||
poppler-utils \
|
poppler-utils \
|
||||||
# OCR MY PDF (unpaper for descew and other advanced featues)
|
# OCR MY PDF (unpaper for descew and other advanced featues)
|
||||||
qpdf \
|
qpdf \
|
||||||
tesseract-ocr-data-eng \
|
tesseract-ocr-data-eng \
|
||||||
|
|
||||||
font-terminus font-dejavu font-noto font-noto-cjk font-awesome font-noto-extra \
|
font-terminus font-dejavu font-noto font-noto-cjk font-awesome font-noto-extra font-liberation font-linux-libertine \
|
||||||
# CV
|
# CV
|
||||||
py3-opencv \
|
py3-opencv \
|
||||||
python3 \
|
python3 \
|
||||||
py3-pip \
|
py3-pip \
|
||||||
py3-pillow@testing \
|
py3-pillow@testing \
|
||||||
@@ -89,7 +89,7 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
|
|||||||
fc-cache -f -v && \
|
fc-cache -f -v && \
|
||||||
chmod +x /scripts/* && \
|
chmod +x /scripts/* && \
|
||||||
chmod +x /scripts/init.sh && \
|
chmod +x /scripts/init.sh && \
|
||||||
# User permissions
|
# User permissions
|
||||||
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
||||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline && \
|
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline && \
|
||||||
chown stirlingpdfuser:stirlingpdfgroup /app.jar
|
chown stirlingpdfuser:stirlingpdfgroup /app.jar
|
||||||
@@ -97,4 +97,4 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
|
|||||||
EXPOSE 8080/tcp
|
EXPOSE 8080/tcp
|
||||||
# Set user and run command
|
# Set user and run command
|
||||||
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
||||||
CMD ["sh", "-c", "java -Dfile.encoding=UTF-8 -jar /app.jar & /opt/venv/bin/unoserver --port 2003 --interface 0.0.0.0"]
|
CMD ["sh", "-c", "java -Dfile.encoding=UTF-8 -jar /app.jar & /opt/venv/bin/unoserver --port 2003 --interface 0.0.0.0"]
|
||||||
|
|||||||
@@ -11,14 +11,12 @@ Fork Stirling-PDF and create a new branch out of `main`.
|
|||||||
Then add a reference to the language in the navbar by adding a new language entry to the dropdown:
|
Then add a reference to the language in the navbar by adding a new language entry to the dropdown:
|
||||||
|
|
||||||
- Edit the file: [languages.html](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/templates/fragments/languages.html)
|
- Edit the file: [languages.html](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/templates/fragments/languages.html)
|
||||||
- Add a flag SVG file to: [flags directory](https://github.com/Stirling-Tools/Stirling-PDF/tree/main/src/main/resources/static/images/flags)
|
|
||||||
|
|
||||||
Any SVG flags are fine; most of the current ones were sourced from [here](https://flagicons.lipis.dev/). If your language isn't represented by a flag, choose a similar one, such as Saudi Arabia's flag for Arabic.
|
|
||||||
|
|
||||||
For example, to add Polish, you would add:
|
For example, to add Polish, you would add:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'pl_PL')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL"> <img th:src="@{'/images/flags/pl.svg'}" alt="icon" width="20" height="15"> Polski</a>
|
<div th:replace="~{fragments/languageEntry :: languageEntry ('pl_PL', 'Polski')}" ></div>
|
||||||
```
|
```
|
||||||
|
|
||||||
The `data-bs-language-code` is the code used to reference the file in the next step.
|
The `data-bs-language-code` is the code used to reference the file in the next step.
|
||||||
|
|||||||
@@ -148,11 +148,11 @@ Stirling-PDF currently supports 39 languages!
|
|||||||
| Simplified Chinese (简体中文) (zh_CN) |  |
|
| Simplified Chinese (简体中文) (zh_CN) |  |
|
||||||
| Slovakian (Slovensky) (sk_SK) |  |
|
| Slovakian (Slovensky) (sk_SK) |  |
|
||||||
| Slovenian (Slovenščina) (sl_SI) |  |
|
| Slovenian (Slovenščina) (sl_SI) |  |
|
||||||
| Spanish (Español) (es_ES) |  |
|
| Spanish (Español) (es_ES) |  |
|
||||||
| Swedish (Svenska) (sv_SE) |  |
|
| Swedish (Svenska) (sv_SE) |  |
|
||||||
| Thai (ไทย) (th_TH) |  |
|
| Thai (ไทย) (th_TH) |  |
|
||||||
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
||||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||||
| Turkish (Türkçe) (tr_TR) |  |
|
| Turkish (Türkçe) (tr_TR) |  |
|
||||||
| Ukrainian (Українська) (uk_UA) |  |
|
| Ukrainian (Українська) (uk_UA) |  |
|
||||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||||
|
|||||||
15
build.gradle
15
build.gradle
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
id "org.springframework.boot" version "3.4.1"
|
id "org.springframework.boot" version "3.4.3"
|
||||||
id "io.spring.dependency-management" version "1.1.7"
|
id "io.spring.dependency-management" version "1.1.7"
|
||||||
id "org.springdoc.openapi-gradle-plugin" version "1.8.0"
|
id "org.springdoc.openapi-gradle-plugin" version "1.8.0"
|
||||||
id "io.swagger.swaggerhub" version "1.3.2"
|
id "io.swagger.swaggerhub" version "1.3.2"
|
||||||
@@ -15,12 +15,12 @@ plugins {
|
|||||||
import com.github.jk1.license.render.*
|
import com.github.jk1.license.render.*
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
springBootVersion = "3.4.2"
|
springBootVersion = "3.4.3"
|
||||||
pdfboxVersion = "3.0.4"
|
pdfboxVersion = "3.0.4"
|
||||||
imageioVersion = "3.12.0"
|
imageioVersion = "3.12.0"
|
||||||
lombokVersion = "1.18.36"
|
lombokVersion = "1.18.36"
|
||||||
bouncycastleVersion = "1.80"
|
bouncycastleVersion = "1.80"
|
||||||
springSecuritySamlVersion = "6.4.2"
|
springSecuritySamlVersion = "6.4.3"
|
||||||
openSamlVersion = "4.3.2"
|
openSamlVersion = "4.3.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,8 +294,8 @@ configurations.all {
|
|||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
//tmp for security bumps
|
//tmp for security bumps
|
||||||
implementation 'ch.qos.logback:logback-core:1.5.15'
|
implementation 'ch.qos.logback:logback-core:1.5.16'
|
||||||
implementation 'ch.qos.logback:logback-classic:1.5.15'
|
implementation 'ch.qos.logback:logback-classic:1.5.16'
|
||||||
|
|
||||||
|
|
||||||
// Exclude vulnerable BouncyCastle version used in tableau
|
// Exclude vulnerable BouncyCastle version used in tableau
|
||||||
@@ -306,8 +306,7 @@ dependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (System.getenv("STIRLING_PDF_DESKTOP_UI") != "false") {
|
if (System.getenv("STIRLING_PDF_DESKTOP_UI") != "false") {
|
||||||
implementation 'org.apache.commons:commons-compress:1.26.0'
|
implementation "me.friwi:jcefmaven:132.3.1"
|
||||||
implementation "me.friwi:jcefmaven:127.3.1"
|
|
||||||
implementation "org.openjfx:javafx-controls:21"
|
implementation "org.openjfx:javafx-controls:21"
|
||||||
implementation "org.openjfx:javafx-swing:21"
|
implementation "org.openjfx:javafx-swing:21"
|
||||||
}
|
}
|
||||||
@@ -332,7 +331,7 @@ dependencies {
|
|||||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
||||||
|
|
||||||
implementation "org.springframework.session:spring-session-core:3.4.1"
|
implementation "org.springframework.session:spring-session-core:3.4.2"
|
||||||
implementation "org.springframework:spring-jdbc:6.2.3"
|
implementation "org.springframework:spring-jdbc:6.2.3"
|
||||||
|
|
||||||
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
|
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.springframework.core.Ordered;
|
|||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import com.posthog.java.shaded.org.json.JSONObject;
|
import com.posthog.java.shaded.org.json.JSONObject;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.springframework.scheduling.annotation.Scheduled;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ import io.github.pixee.security.SystemCommand;
|
|||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.annotation.PreDestroy;
|
import jakarta.annotation.PreDestroy;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.UI.WebBrowser;
|
import stirling.software.SPDF.UI.WebBrowser;
|
||||||
import stirling.software.SPDF.config.ConfigInitializer;
|
import stirling.software.SPDF.config.ConfigInitializer;
|
||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
|
|||||||
@@ -34,11 +34,14 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import jakarta.annotation.PreDestroy;
|
import jakarta.annotation.PreDestroy;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import me.friwi.jcefmaven.CefAppBuilder;
|
import me.friwi.jcefmaven.CefAppBuilder;
|
||||||
import me.friwi.jcefmaven.EnumProgress;
|
import me.friwi.jcefmaven.EnumProgress;
|
||||||
import me.friwi.jcefmaven.MavenCefAppHandlerAdapter;
|
import me.friwi.jcefmaven.MavenCefAppHandlerAdapter;
|
||||||
import me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler;
|
import me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler;
|
||||||
|
|
||||||
import stirling.software.SPDF.UI.WebBrowser;
|
import stirling.software.SPDF.UI.WebBrowser;
|
||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
import stirling.software.SPDF.utils.UIScaling;
|
import stirling.software.SPDF.utils.UIScaling;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import javax.swing.*;
|
|||||||
import io.github.pixee.security.BoundedLineReader;
|
import io.github.pixee.security.BoundedLineReader;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.utils.UIScaling;
|
import stirling.software.SPDF.utils.UIScaling;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.springframework.core.io.ResourceLoader;
|
|||||||
import org.thymeleaf.spring6.SpringTemplateEngine;
|
import org.thymeleaf.spring6.SpringTemplateEngine;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -127,15 +128,6 @@ public class AppConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name = "bookAndHtmlFormatsInstalled")
|
|
||||||
public boolean bookAndHtmlFormatsInstalled() {
|
|
||||||
String installOps = System.getProperty("INSTALL_BOOK_AND_ADVANCED_HTML_OPS");
|
|
||||||
if (installOps == null) {
|
|
||||||
installOps = System.getenv("INSTALL_BOOK_AND_ADVANCED_HTML_OPS");
|
|
||||||
}
|
|
||||||
return "true".equalsIgnoreCase(installOps);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ConditionalOnMissingClass("stirling.software.SPDF.config.security.SecurityConfiguration")
|
@ConditionalOnMissingClass("stirling.software.SPDF.config.security.SecurityConfiguration")
|
||||||
@Bean(name = "activSecurity")
|
@Bean(name = "activSecurity")
|
||||||
public boolean missingActivSecurity() {
|
public boolean missingActivSecurity() {
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ package stirling.software.SPDF.config;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.config.interfaces.ShowAdminInterface;
|
import stirling.software.SPDF.config.interfaces.ShowAdminInterface;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
@Service
|
@Configuration
|
||||||
class AppUpdateService {
|
class AppUpdateService {
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package stirling.software.SPDF.config;
|
package stirling.software.SPDF.config;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -9,30 +8,24 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.context.annotation.DependsOn;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@DependsOn({"bookAndHtmlFormatsInstalled"})
|
|
||||||
public class EndpointConfiguration {
|
public class EndpointConfiguration {
|
||||||
|
|
||||||
private static final String REMOVE_BLANKS = "remove-blanks";
|
private static final String REMOVE_BLANKS = "remove-blanks";
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
private Map<String, Boolean> endpointStatuses = new ConcurrentHashMap<>();
|
private Map<String, Boolean> endpointStatuses = new ConcurrentHashMap<>();
|
||||||
private Map<String, Set<String>> endpointGroups = new ConcurrentHashMap<>();
|
private Map<String, Set<String>> endpointGroups = new ConcurrentHashMap<>();
|
||||||
private boolean bookAndHtmlFormatsInstalled;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public EndpointConfiguration(
|
public EndpointConfiguration(ApplicationProperties applicationProperties) {
|
||||||
ApplicationProperties applicationProperties,
|
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
|
|
||||||
this.applicationProperties = applicationProperties;
|
this.applicationProperties = applicationProperties;
|
||||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
|
||||||
init();
|
init();
|
||||||
processEnvironmentConfigs();
|
processEnvironmentConfigs();
|
||||||
}
|
}
|
||||||
@@ -197,8 +190,8 @@ public class EndpointConfiguration {
|
|||||||
addEndpointToGroup("LibreOffice", "pdf-to-html");
|
addEndpointToGroup("LibreOffice", "pdf-to-html");
|
||||||
addEndpointToGroup("LibreOffice", "pdf-to-xml");
|
addEndpointToGroup("LibreOffice", "pdf-to-xml");
|
||||||
|
|
||||||
// Unoconv
|
// Unoconvert
|
||||||
addEndpointToGroup("Unoconv", "file-to-pdf");
|
addEndpointToGroup("Unoconvert", "file-to-pdf");
|
||||||
|
|
||||||
// qpdf
|
// qpdf
|
||||||
addEndpointToGroup("qpdf", "compress-pdf");
|
addEndpointToGroup("qpdf", "compress-pdf");
|
||||||
@@ -272,12 +265,6 @@ public class EndpointConfiguration {
|
|||||||
List<String> endpointsToRemove = applicationProperties.getEndpoints().getToRemove();
|
List<String> endpointsToRemove = applicationProperties.getEndpoints().getToRemove();
|
||||||
List<String> groupsToRemove = applicationProperties.getEndpoints().getGroupsToRemove();
|
List<String> groupsToRemove = applicationProperties.getEndpoints().getGroupsToRemove();
|
||||||
|
|
||||||
if (!bookAndHtmlFormatsInstalled) {
|
|
||||||
if (groupsToRemove == null) {
|
|
||||||
groupsToRemove = new ArrayList<>();
|
|
||||||
}
|
|
||||||
groupsToRemove.add("Calibre");
|
|
||||||
}
|
|
||||||
if (endpointsToRemove != null) {
|
if (endpointsToRemove != null) {
|
||||||
for (String endpoint : endpointsToRemove) {
|
for (String endpoint : endpointsToRemove) {
|
||||||
disableEndpoint(endpoint.trim());
|
disableEndpoint(endpoint.trim());
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import java.util.stream.Collectors;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -16,21 +17,29 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
public class ExternalAppDepConfig {
|
public class ExternalAppDepConfig {
|
||||||
|
|
||||||
private final EndpointConfiguration endpointConfiguration;
|
private final EndpointConfiguration endpointConfiguration;
|
||||||
private final Map<String, List<String>> commandToGroupMapping =
|
|
||||||
new HashMap<>() {
|
|
||||||
|
|
||||||
{
|
private final String weasyprintPath;
|
||||||
put("soffice", List.of("LibreOffice"));
|
private final String unoconvPath;
|
||||||
put("/opt/venv/bin/weasyprint", List.of("Weasyprint"));
|
private final Map<String, List<String>> commandToGroupMapping;
|
||||||
put("pdftohtml", List.of("Pdftohtml"));
|
|
||||||
put("/opt/venv/bin/unoconvert", List.of("Unoconv"));
|
|
||||||
put("qpdf", List.of("qpdf"));
|
|
||||||
put("tesseract", List.of("tesseract"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public ExternalAppDepConfig(EndpointConfiguration endpointConfiguration) {
|
public ExternalAppDepConfig(
|
||||||
|
EndpointConfiguration endpointConfiguration, RuntimePathConfig runtimePathConfig) {
|
||||||
this.endpointConfiguration = endpointConfiguration;
|
this.endpointConfiguration = endpointConfiguration;
|
||||||
|
weasyprintPath = runtimePathConfig.getWeasyPrintPath();
|
||||||
|
unoconvPath = runtimePathConfig.getUnoConvertPath();
|
||||||
|
|
||||||
|
commandToGroupMapping =
|
||||||
|
new HashMap<>() {
|
||||||
|
|
||||||
|
{
|
||||||
|
put("soffice", List.of("LibreOffice"));
|
||||||
|
put(weasyprintPath, List.of("Weasyprint"));
|
||||||
|
put("pdftohtml", List.of("Pdftohtml"));
|
||||||
|
put(unoconvPath, List.of("Unoconvert"));
|
||||||
|
put("qpdf", List.of("qpdf"));
|
||||||
|
put("tesseract", List.of("tesseract"));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCommandAvailable(String command) {
|
private boolean isCommandAvailable(String command) {
|
||||||
@@ -101,9 +110,9 @@ public class ExternalAppDepConfig {
|
|||||||
checkDependencyAndDisableGroup("tesseract");
|
checkDependencyAndDisableGroup("tesseract");
|
||||||
checkDependencyAndDisableGroup("soffice");
|
checkDependencyAndDisableGroup("soffice");
|
||||||
checkDependencyAndDisableGroup("qpdf");
|
checkDependencyAndDisableGroup("qpdf");
|
||||||
checkDependencyAndDisableGroup("/opt/venv/bin/weasyprint");
|
checkDependencyAndDisableGroup(weasyprintPath);
|
||||||
checkDependencyAndDisableGroup("pdftohtml");
|
checkDependencyAndDisableGroup("pdftohtml");
|
||||||
checkDependencyAndDisableGroup("/opt/venv/bin/unoconvert");
|
checkDependencyAndDisableGroup(unoconvPath);
|
||||||
// Special handling for Python/OpenCV dependencies
|
// Special handling for Python/OpenCV dependencies
|
||||||
boolean pythonAvailable = isCommandAvailable("python3") || isCommandAvailable("python");
|
boolean pythonAvailable = isCommandAvailable("python3") || isCommandAvailable("python");
|
||||||
if (!pythonAvailable) {
|
if (!pythonAvailable) {
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ import org.springframework.stereotype.Component;
|
|||||||
import io.micrometer.common.util.StringUtils;
|
import io.micrometer.common.util.StringUtils;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ public class InstallationPathConfig {
|
|||||||
// Root paths
|
// Root paths
|
||||||
private static final String LOG_PATH;
|
private static final String LOG_PATH;
|
||||||
private static final String CONFIG_PATH;
|
private static final String CONFIG_PATH;
|
||||||
private static final String PIPELINE_PATH;
|
|
||||||
private static final String CUSTOM_FILES_PATH;
|
private static final String CUSTOM_FILES_PATH;
|
||||||
private static final String CLIENT_WEBUI_PATH;
|
private static final String CLIENT_WEBUI_PATH;
|
||||||
|
|
||||||
@@ -19,11 +18,6 @@ public class InstallationPathConfig {
|
|||||||
private static final String SETTINGS_PATH;
|
private static final String SETTINGS_PATH;
|
||||||
private static final String CUSTOM_SETTINGS_PATH;
|
private static final String CUSTOM_SETTINGS_PATH;
|
||||||
|
|
||||||
// Pipeline paths
|
|
||||||
private static final String PIPELINE_WATCHED_FOLDERS_PATH;
|
|
||||||
private static final String PIPELINE_FINISHED_FOLDERS_PATH;
|
|
||||||
private static final String PIPELINE_DEFAULT_WEB_UI_CONFIGS;
|
|
||||||
|
|
||||||
// Custom file paths
|
// Custom file paths
|
||||||
private static final String STATIC_PATH;
|
private static final String STATIC_PATH;
|
||||||
private static final String TEMPLATES_PATH;
|
private static final String TEMPLATES_PATH;
|
||||||
@@ -35,7 +29,6 @@ public class InstallationPathConfig {
|
|||||||
// Initialize root paths
|
// Initialize root paths
|
||||||
LOG_PATH = BASE_PATH + "logs" + File.separator;
|
LOG_PATH = BASE_PATH + "logs" + File.separator;
|
||||||
CONFIG_PATH = BASE_PATH + "configs" + File.separator;
|
CONFIG_PATH = BASE_PATH + "configs" + File.separator;
|
||||||
PIPELINE_PATH = BASE_PATH + "pipeline" + File.separator;
|
|
||||||
CUSTOM_FILES_PATH = BASE_PATH + "customFiles" + File.separator;
|
CUSTOM_FILES_PATH = BASE_PATH + "customFiles" + File.separator;
|
||||||
CLIENT_WEBUI_PATH = BASE_PATH + "clientWebUI" + File.separator;
|
CLIENT_WEBUI_PATH = BASE_PATH + "clientWebUI" + File.separator;
|
||||||
|
|
||||||
@@ -43,11 +36,6 @@ public class InstallationPathConfig {
|
|||||||
SETTINGS_PATH = CONFIG_PATH + "settings.yml";
|
SETTINGS_PATH = CONFIG_PATH + "settings.yml";
|
||||||
CUSTOM_SETTINGS_PATH = CONFIG_PATH + "custom_settings.yml";
|
CUSTOM_SETTINGS_PATH = CONFIG_PATH + "custom_settings.yml";
|
||||||
|
|
||||||
// Initialize pipeline paths
|
|
||||||
PIPELINE_WATCHED_FOLDERS_PATH = PIPELINE_PATH + "watchedFolders" + File.separator;
|
|
||||||
PIPELINE_FINISHED_FOLDERS_PATH = PIPELINE_PATH + "finishedFolders" + File.separator;
|
|
||||||
PIPELINE_DEFAULT_WEB_UI_CONFIGS = PIPELINE_PATH + "defaultWebUIConfigs" + File.separator;
|
|
||||||
|
|
||||||
// Initialize custom file paths
|
// Initialize custom file paths
|
||||||
STATIC_PATH = CUSTOM_FILES_PATH + "static" + File.separator;
|
STATIC_PATH = CUSTOM_FILES_PATH + "static" + File.separator;
|
||||||
TEMPLATES_PATH = CUSTOM_FILES_PATH + "templates" + File.separator;
|
TEMPLATES_PATH = CUSTOM_FILES_PATH + "templates" + File.separator;
|
||||||
@@ -92,10 +80,6 @@ public class InstallationPathConfig {
|
|||||||
return CONFIG_PATH;
|
return CONFIG_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getPipelinePath() {
|
|
||||||
return PIPELINE_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getCustomFilesPath() {
|
public static String getCustomFilesPath() {
|
||||||
return CUSTOM_FILES_PATH;
|
return CUSTOM_FILES_PATH;
|
||||||
}
|
}
|
||||||
@@ -112,18 +96,6 @@ public class InstallationPathConfig {
|
|||||||
return CUSTOM_SETTINGS_PATH;
|
return CUSTOM_SETTINGS_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getPipelineWatchedFoldersDir() {
|
|
||||||
return PIPELINE_WATCHED_FOLDERS_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getPipelineFinishedFoldersDir() {
|
|
||||||
return PIPELINE_FINISHED_FOLDERS_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getPipelineDefaultWebUIConfigsDir() {
|
|
||||||
return PIPELINE_DEFAULT_WEB_UI_CONFIGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getStaticPath() {
|
public static String getStaticPath() {
|
||||||
return STATIC_PATH;
|
return STATIC_PATH;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import jakarta.servlet.ServletException;
|
|||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.servlet.http.HttpSession;
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
|
||||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import com.posthog.java.PostHog;
|
import com.posthog.java.PostHog;
|
||||||
|
|
||||||
import jakarta.annotation.PreDestroy;
|
import jakarta.annotation.PreDestroy;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package stirling.software.SPDF.config;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties.CustomPaths.Operations;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties.CustomPaths.Pipeline;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
@Getter
|
||||||
|
public class RuntimePathConfig {
|
||||||
|
private final ApplicationProperties properties;
|
||||||
|
private final String basePath;
|
||||||
|
private final String weasyPrintPath;
|
||||||
|
private final String unoConvertPath;
|
||||||
|
|
||||||
|
// Pipeline paths
|
||||||
|
private final String pipelineWatchedFoldersPath;
|
||||||
|
private final String pipelineFinishedFoldersPath;
|
||||||
|
private final String pipelineDefaultWebUiConfigs;
|
||||||
|
private final String pipelinePath;
|
||||||
|
|
||||||
|
public RuntimePathConfig(ApplicationProperties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
this.basePath = InstallationPathConfig.getPath();
|
||||||
|
|
||||||
|
String pipelinePath = basePath + "pipeline" + File.separator;
|
||||||
|
String watchedFoldersPath = pipelinePath + "watchedFolders" + File.separator;
|
||||||
|
String finishedFoldersPath = pipelinePath + "finishedFolders" + File.separator;
|
||||||
|
String webUiConfigsPath = pipelinePath + "defaultWebUIConfigs" + File.separator;
|
||||||
|
|
||||||
|
Pipeline pipeline = properties.getSystem().getCustomPaths().getPipeline();
|
||||||
|
if (pipeline != null) {
|
||||||
|
if (!StringUtils.isEmpty(pipeline.getWatchedFoldersDir())) {
|
||||||
|
watchedFoldersPath = pipeline.getWatchedFoldersDir();
|
||||||
|
}
|
||||||
|
if (!StringUtils.isEmpty(pipeline.getFinishedFoldersDir())) {
|
||||||
|
finishedFoldersPath = pipeline.getFinishedFoldersDir();
|
||||||
|
}
|
||||||
|
if (!StringUtils.isEmpty(pipeline.getWebUIConfigsDir())) {
|
||||||
|
webUiConfigsPath = pipeline.getWebUIConfigsDir();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pipelinePath = pipelinePath;
|
||||||
|
this.pipelineWatchedFoldersPath = watchedFoldersPath;
|
||||||
|
this.pipelineFinishedFoldersPath = finishedFoldersPath;
|
||||||
|
this.pipelineDefaultWebUiConfigs = webUiConfigsPath;
|
||||||
|
|
||||||
|
boolean isDocker = isRunningInDocker();
|
||||||
|
|
||||||
|
// Initialize Operation paths
|
||||||
|
String weasyPrintPath = isDocker ? "/opt/venv/bin/weasyprint" : "weasyprint";
|
||||||
|
String unoConvertPath = isDocker ? "/opt/venv/bin/unoconvert" : "unoconvert";
|
||||||
|
|
||||||
|
|
||||||
|
// Check for custom operation paths
|
||||||
|
Operations operations = properties.getSystem().getCustomPaths().getOperations();
|
||||||
|
if (operations != null) {
|
||||||
|
if (!StringUtils.isEmpty(operations.getWeasyprint())) {
|
||||||
|
weasyPrintPath = operations.getWeasyprint();
|
||||||
|
}
|
||||||
|
if (!StringUtils.isEmpty(operations.getUnoconvert())) {
|
||||||
|
unoConvertPath = operations.getUnoconvert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign operations final fields
|
||||||
|
this.weasyPrintPath = weasyPrintPath;
|
||||||
|
this.unoConvertPath = unoConvertPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRunningInDocker() {
|
||||||
|
return Files.exists(Paths.get("/.dockerenv"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -14,7 +14,9 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa
|
|||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import jakarta.servlet.ServletException;
|
|||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.servlet.http.HttpSession;
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ import com.coveo.saml.SamlClient;
|
|||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.SPDFApplication;
|
import stirling.software.SPDF.SPDFApplication;
|
||||||
import stirling.software.SPDF.config.security.saml2.CertificateUtils;
|
import stirling.software.SPDF.config.security.saml2.CertificateUtils;
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import jakarta.servlet.ServletException;
|
|||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.servlet.http.HttpSession;
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
import jakarta.servlet.*;
|
import jakarta.servlet.*;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import stirling.software.SPDF.utils.RequestUriUtils;
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
public class IPRateLimitingFilter implements Filter {
|
public class IPRateLimitingFilter implements Filter {
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import java.util.UUID;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.Role;
|
import stirling.software.SPDF.model.Role;
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.AttemptCounter;
|
import stirling.software.SPDF.model.AttemptCounter;
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.springframework.security.web.savedrequest.NullRequestCache;
|
|||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationFailureHandler;
|
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationFailureHandler;
|
||||||
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationSuccessHandler;
|
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationSuccessHandler;
|
||||||
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService;
|
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService;
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ import jakarta.servlet.FilterChain;
|
|||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
||||||
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
||||||
import stirling.software.SPDF.model.ApiKeyAuthenticationToken;
|
import stirling.software.SPDF.model.ApiKeyAuthenticationToken;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import jakarta.servlet.FilterChain;
|
|||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.Role;
|
import stirling.software.SPDF.model.Role;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
||||||
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
||||||
@@ -139,8 +140,8 @@ public class UserService implements UserServiceInterface {
|
|||||||
User user =
|
User user =
|
||||||
findByUsernameIgnoreCase(username)
|
findByUsernameIgnoreCase(username)
|
||||||
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
|
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
|
||||||
if(user.getApiKey() == null || user.getApiKey().length() == 0) {
|
if (user.getApiKey() == null || user.getApiKey().length() == 0) {
|
||||||
user = addApiKeyToUser(username);
|
user = addApiKeyToUser(username);
|
||||||
}
|
}
|
||||||
return user.getApiKey();
|
return user.getApiKey();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.springframework.jdbc.datasource.init.ScriptException;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
import stirling.software.SPDF.config.interfaces.DatabaseInterface;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa
|
|||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import jakarta.servlet.ServletException;
|
|||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.servlet.http.HttpSession;
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.LoginAttemptService;
|
import stirling.software.SPDF.config.security.LoginAttemptService;
|
||||||
import stirling.software.SPDF.config.security.UserService;
|
import stirling.software.SPDF.config.security.UserService;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
|
|||||||
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.LoginAttemptService;
|
import stirling.software.SPDF.config.security.LoginAttemptService;
|
||||||
import stirling.software.SPDF.config.security.UserService;
|
import stirling.software.SPDF.config.security.UserService;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.springframework.security.oauth2.client.registration.InMemoryClientReg
|
|||||||
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
|
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.UserService;
|
import stirling.software.SPDF.config.security.UserService;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa
|
|||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|||||||
@@ -12,8 +12,10 @@ import jakarta.servlet.ServletException;
|
|||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.servlet.http.HttpSession;
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.LoginAttemptService;
|
import stirling.software.SPDF.config.security.LoginAttemptService;
|
||||||
import stirling.software.SPDF.config.security.UserService;
|
import stirling.software.SPDF.config.security.UserService;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.springframework.security.saml2.provider.service.authentication.OpenSa
|
|||||||
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
|
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.UserService;
|
import stirling.software.SPDF.config.security.UserService;
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ import org.springframework.security.saml2.provider.service.registration.Saml2Mes
|
|||||||
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
|
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import jakarta.servlet.http.HttpSessionEvent;
|
import jakarta.servlet.http.HttpSessionEvent;
|
||||||
import jakarta.servlet.http.HttpSessionListener;
|
import jakarta.servlet.http.HttpSessionListener;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.springframework.security.oauth2.core.user.OAuth2User;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
||||||
import stirling.software.SPDF.model.SessionEntity;
|
import stirling.software.SPDF.model.SessionEntity;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.springframework.data.repository.query.Param;
|
|||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.SessionEntity;
|
import stirling.software.SPDF.model.SessionEntity;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import io.swagger.v3.oas.annotations.Hidden;
|
import io.swagger.v3.oas.annotations.Hidden;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import stirling.software.SPDF.service.LanguageService;
|
import stirling.software.SPDF.service.LanguageService;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import io.swagger.v3.oas.annotations.Parameter;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.database.DatabaseService;
|
import stirling.software.SPDF.config.security.database.DatabaseService;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.MergePdfsRequest;
|
import stirling.software.SPDF.model.api.general.MergePdfsRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.SortTypes;
|
import stirling.software.SPDF.model.SortTypes;
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
import stirling.software.SPDF.model.api.general.RearrangePagesRequest;
|
import stirling.software.SPDF.model.api.general.RearrangePagesRequest;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import lombok.Data;
|
|||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.PdfMetadata;
|
import stirling.software.SPDF.model.PdfMetadata;
|
||||||
import stirling.software.SPDF.model.api.SplitPdfByChaptersRequest;
|
import stirling.software.SPDF.model.api.SplitPdfByChaptersRequest;
|
||||||
import stirling.software.SPDF.service.PdfMetadataService;
|
import stirling.software.SPDF.service.PdfMetadataService;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.SplitPdfBySizeOrCountRequest;
|
import stirling.software.SPDF.model.api.general.SplitPdfBySizeOrCountRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.UserService;
|
import stirling.software.SPDF.config.security.UserService;
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
||||||
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
package stirling.software.SPDF.controller.api.converters;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.GeneralFile;
|
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
|
||||||
import stirling.software.SPDF.utils.FileToPdf;
|
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
|
||||||
|
|
||||||
// @RestController
|
|
||||||
// @Tag(name = "Convert", description = "Convert APIs")
|
|
||||||
// @RequestMapping("/api/v1/convert")
|
|
||||||
public class ConvertBookToPDFController {
|
|
||||||
|
|
||||||
private final boolean bookAndHtmlFormatsInstalled;
|
|
||||||
|
|
||||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public ConvertBookToPDFController(
|
|
||||||
CustomPDDocumentFactory pdfDocumentFactory,
|
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
|
|
||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
|
||||||
this.bookAndHtmlFormatsInstalled = 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 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 (!bookAndHtmlFormatsInstalled) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"bookAndHtmlFormatsInstalled flag is False, this functionality is not available");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileInput == null) {
|
|
||||||
throw new IllegalArgumentException("Please provide a file for conversion.");
|
|
||||||
}
|
|
||||||
|
|
||||||
String originalFilename = Filenames.toSimpleFileName(fileInput.getOriginalFilename());
|
|
||||||
|
|
||||||
if (originalFilename != null) {
|
|
||||||
String originalFilenameLower = originalFilename.toLowerCase();
|
|
||||||
if (!originalFilenameLower.endsWith(".epub")
|
|
||||||
&& !originalFilenameLower.endsWith(".mobi")
|
|
||||||
&& !originalFilenameLower.endsWith(".azw3")
|
|
||||||
&& !originalFilenameLower.endsWith(".fb2")
|
|
||||||
&& !originalFilenameLower.endsWith(".txt")
|
|
||||||
&& !originalFilenameLower.endsWith(".docx")) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"File must be in .epub, .mobi, .azw3, .fb2, .txt, or .docx format.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
byte[] pdfBytes = FileToPdf.convertBookTypeToPdf(fileInput.getBytes(), originalFilename);
|
|
||||||
|
|
||||||
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
|
||||||
|
|
||||||
String outputFilename =
|
|
||||||
originalFilename.replaceFirst("[.][^.]+$", "")
|
|
||||||
+ ".pdf"; // Remove file extension and append .pdf
|
|
||||||
|
|
||||||
return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package stirling.software.SPDF.controller.api.converters;
|
package stirling.software.SPDF.controller.api.converters;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -13,6 +12,7 @@ import io.github.pixee.security.Filenames;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.config.RuntimePathConfig;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
@@ -24,20 +24,21 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
@RequestMapping("/api/v1/convert")
|
@RequestMapping("/api/v1/convert")
|
||||||
public class ConvertHtmlToPDF {
|
public class ConvertHtmlToPDF {
|
||||||
|
|
||||||
private final boolean bookAndHtmlFormatsInstalled;
|
|
||||||
|
|
||||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
|
private final RuntimePathConfig runtimePathConfig;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ConvertHtmlToPDF(
|
public ConvertHtmlToPDF(
|
||||||
CustomPDDocumentFactory pdfDocumentFactory,
|
CustomPDDocumentFactory pdfDocumentFactory,
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled,
|
ApplicationProperties applicationProperties,
|
||||||
ApplicationProperties applicationProperties) {
|
RuntimePathConfig runtimePathConfig) {
|
||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
|
||||||
this.applicationProperties = applicationProperties;
|
this.applicationProperties = applicationProperties;
|
||||||
|
this.runtimePathConfig = runtimePathConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
||||||
@@ -65,10 +66,10 @@ public class ConvertHtmlToPDF {
|
|||||||
|
|
||||||
byte[] pdfBytes =
|
byte[] pdfBytes =
|
||||||
FileToPdf.convertHtmlToPdf(
|
FileToPdf.convertHtmlToPdf(
|
||||||
|
runtimePathConfig.getWeasyPrintPath(),
|
||||||
request,
|
request,
|
||||||
fileInput.getBytes(),
|
fileInput.getBytes(),
|
||||||
originalFilename,
|
originalFilename,
|
||||||
bookAndHtmlFormatsInstalled,
|
|
||||||
disableSanitize);
|
disableSanitize);
|
||||||
|
|
||||||
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.ConvertToImageRequest;
|
import stirling.software.SPDF.model.api.converters.ConvertToImageRequest;
|
||||||
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import org.commonmark.parser.Parser;
|
|||||||
import org.commonmark.renderer.html.AttributeProvider;
|
import org.commonmark.renderer.html.AttributeProvider;
|
||||||
import org.commonmark.renderer.html.HtmlRenderer;
|
import org.commonmark.renderer.html.HtmlRenderer;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -23,6 +22,7 @@ import io.github.pixee.security.Filenames;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.config.RuntimePathConfig;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.api.GeneralFile;
|
import stirling.software.SPDF.model.api.GeneralFile;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
@@ -34,20 +34,20 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
@RequestMapping("/api/v1/convert")
|
@RequestMapping("/api/v1/convert")
|
||||||
public class ConvertMarkdownToPdf {
|
public class ConvertMarkdownToPdf {
|
||||||
|
|
||||||
private final boolean bookAndHtmlFormatsInstalled;
|
|
||||||
|
|
||||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
private final RuntimePathConfig runtimePathConfig;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ConvertMarkdownToPdf(
|
public ConvertMarkdownToPdf(
|
||||||
CustomPDDocumentFactory pdfDocumentFactory,
|
CustomPDDocumentFactory pdfDocumentFactory,
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled,
|
ApplicationProperties applicationProperties,
|
||||||
ApplicationProperties applicationProperties) {
|
RuntimePathConfig runtimePathConfig) {
|
||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
|
||||||
this.applicationProperties = applicationProperties;
|
this.applicationProperties = applicationProperties;
|
||||||
|
this.runtimePathConfig = runtimePathConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
||||||
@@ -86,10 +86,10 @@ public class ConvertMarkdownToPdf {
|
|||||||
|
|
||||||
byte[] pdfBytes =
|
byte[] pdfBytes =
|
||||||
FileToPdf.convertHtmlToPdf(
|
FileToPdf.convertHtmlToPdf(
|
||||||
|
runtimePathConfig.getWeasyPrintPath(),
|
||||||
null,
|
null,
|
||||||
htmlContent.getBytes(),
|
htmlContent.getBytes(),
|
||||||
"converted.html",
|
"converted.html",
|
||||||
bookAndHtmlFormatsInstalled,
|
|
||||||
disableSanitize);
|
disableSanitize);
|
||||||
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
||||||
String outputFilename =
|
String outputFilename =
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import io.github.pixee.security.Filenames;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.config.RuntimePathConfig;
|
||||||
import stirling.software.SPDF.model.api.GeneralFile;
|
import stirling.software.SPDF.model.api.GeneralFile;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
@@ -34,10 +35,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
public class ConvertOfficeController {
|
public class ConvertOfficeController {
|
||||||
|
|
||||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
private final RuntimePathConfig runtimePathConfig;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ConvertOfficeController(CustomPDDocumentFactory pdfDocumentFactory) {
|
public ConvertOfficeController(
|
||||||
|
CustomPDDocumentFactory pdfDocumentFactory, RuntimePathConfig runtimePathConfig) {
|
||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
this.runtimePathConfig = runtimePathConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public File convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
|
public File convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
|
||||||
@@ -61,7 +65,7 @@ public class ConvertOfficeController {
|
|||||||
List<String> command =
|
List<String> command =
|
||||||
new ArrayList<>(
|
new ArrayList<>(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
"/opt/venv/bin/unoconvert",
|
runtimePathConfig.getUnoConvertPath(),
|
||||||
"--port",
|
"--port",
|
||||||
"2003",
|
"2003",
|
||||||
"--convert-to",
|
"--convert-to",
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
package stirling.software.SPDF.controller.api.converters;
|
|
||||||
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToBookRequest;
|
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
|
||||||
|
|
||||||
// @RestController
|
|
||||||
// @Tag(name = "Convert", description = "Convert APIs")
|
|
||||||
// @RequestMapping("/api/v1/convert")
|
|
||||||
public class ConvertPDFToBookController {
|
|
||||||
|
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
|
||||||
private final boolean bookAndHtmlFormatsInstalled;
|
|
||||||
|
|
||||||
public ConvertPDFToBookController(
|
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
|
|
||||||
this.bookAndHtmlFormatsInstalled = 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 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 (!bookAndHtmlFormatsInstalled) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"bookAndHtmlFormatsInstalled flag is False, this functionality is not available");
|
|
||||||
}
|
|
||||||
if (fileInput == null) {
|
|
||||||
throw new IllegalArgumentException("Please provide a file for conversion.");
|
|
||||||
}
|
|
||||||
// Validate the output format
|
|
||||||
String outputFormat = request.getOutputFormat().toLowerCase();
|
|
||||||
List<String> allowedFormats =
|
|
||||||
Arrays.asList(
|
|
||||||
"epub", "mobi", "azw3", "docx", "rtf", "txt", "html", "lit", "fb2", "pdb",
|
|
||||||
"lrf");
|
|
||||||
if (!allowedFormats.contains(outputFormat)) {
|
|
||||||
throw new IllegalArgumentException("Invalid output format: " + outputFormat);
|
|
||||||
}
|
|
||||||
byte[] outputFileBytes;
|
|
||||||
List<String> command = new ArrayList<>();
|
|
||||||
Path tempOutputFile =
|
|
||||||
Files.createTempFile(
|
|
||||||
"output_", // Use the output format for the file extension
|
|
||||||
"." + outputFormat);
|
|
||||||
Path tempInputFile = null;
|
|
||||||
try {
|
|
||||||
// Create temp input file from the provided PDF
|
|
||||||
// Assuming input is always PDF
|
|
||||||
tempInputFile = Files.createTempFile("input_", ".pdf");
|
|
||||||
Files.write(tempInputFile, fileInput.getBytes());
|
|
||||||
command.add("ebook-convert");
|
|
||||||
command.add(tempInputFile.toString());
|
|
||||||
command.add(tempOutputFile.toString());
|
|
||||||
ProcessExecutorResult returnCode =
|
|
||||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.CALIBRE)
|
|
||||||
.runCommandWithOutputHandling(command);
|
|
||||||
outputFileBytes = Files.readAllBytes(tempOutputFile);
|
|
||||||
} finally {
|
|
||||||
// Clean up temporary files
|
|
||||||
if (tempInputFile != null) {
|
|
||||||
Files.deleteIfExists(tempInputFile);
|
|
||||||
}
|
|
||||||
Files.deleteIfExists(tempOutputFile);
|
|
||||||
}
|
|
||||||
String outputFilename =
|
|
||||||
Filenames.toSimpleFileName(fileInput.getOriginalFilename())
|
|
||||||
.replaceFirst("[.][^.]+$", "")
|
|
||||||
+ "."
|
|
||||||
+ // Remove file extension and append .pdf
|
|
||||||
outputFormat;
|
|
||||||
return WebResponseUtils.bytesToWebResponse(outputFileBytes, outputFilename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToPdfARequest;
|
import stirling.software.SPDF.model.api.converters.PdfToPdfARequest;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.config.RuntimePathConfig;
|
||||||
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
@@ -32,10 +34,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
public class ConvertWebsiteToPDF {
|
public class ConvertWebsiteToPDF {
|
||||||
|
|
||||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
private final RuntimePathConfig runtimePathConfig;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ConvertWebsiteToPDF(CustomPDDocumentFactory pdfDocumentFactory) {
|
public ConvertWebsiteToPDF(
|
||||||
|
CustomPDDocumentFactory pdfDocumentFactory, RuntimePathConfig runtimePathConfig) {
|
||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
this.runtimePathConfig = runtimePathConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/url/pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/url/pdf")
|
||||||
@@ -65,7 +70,7 @@ public class ConvertWebsiteToPDF {
|
|||||||
|
|
||||||
// Prepare the WeasyPrint command
|
// Prepare the WeasyPrint command
|
||||||
List<String> command = new ArrayList<>();
|
List<String> command = new ArrayList<>();
|
||||||
command.add("/opt/venv/bin/weasyprint");
|
command.add(runtimePathConfig.getWeasyPrintPath());
|
||||||
command.add(URL);
|
command.add(URL);
|
||||||
command.add(tempOutputFile.toString());
|
command.add(tempOutputFile.toString());
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,12 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
import stirling.software.SPDF.pdf.FlexibleCSVWriter;
|
import stirling.software.SPDF.pdf.FlexibleCSVWriter;
|
||||||
|
|
||||||
import technology.tabula.ObjectExtractor;
|
import technology.tabula.ObjectExtractor;
|
||||||
import technology.tabula.Page;
|
import technology.tabula.Page;
|
||||||
import technology.tabula.Table;
|
import technology.tabula.Table;
|
||||||
@@ -51,22 +54,20 @@ public class ExtractCSVController {
|
|||||||
try (PDDocument document = Loader.loadPDF(form.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(form.getFileInput().getBytes())) {
|
||||||
List<Integer> pages = form.getPageNumbersList(document, true);
|
List<Integer> pages = form.getPageNumbersList(document, true);
|
||||||
SpreadsheetExtractionAlgorithm sea = new SpreadsheetExtractionAlgorithm();
|
SpreadsheetExtractionAlgorithm sea = new SpreadsheetExtractionAlgorithm();
|
||||||
CSVFormat format = CSVFormat.EXCEL.builder()
|
CSVFormat format =
|
||||||
.setEscape('"')
|
CSVFormat.EXCEL.builder().setEscape('"').setQuoteMode(QuoteMode.ALL).build();
|
||||||
.setQuoteMode(QuoteMode.ALL)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
for (int pageNum : pages) {
|
for (int pageNum : pages) {
|
||||||
try (ObjectExtractor extractor = new ObjectExtractor(document)) {
|
try (ObjectExtractor extractor = new ObjectExtractor(document)) {
|
||||||
log.info("{}",pageNum);
|
log.info("{}", pageNum);
|
||||||
Page page = extractor.extract(pageNum);
|
Page page = extractor.extract(pageNum);
|
||||||
List<Table> tables = sea.extract(page);
|
List<Table> tables = sea.extract(page);
|
||||||
|
|
||||||
for (int i = 0; i < tables.size(); i++) {
|
for (int i = 0; i < tables.size(); i++) {
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
FlexibleCSVWriter csvWriter = new FlexibleCSVWriter(format);
|
FlexibleCSVWriter csvWriter = new FlexibleCSVWriter(format);
|
||||||
csvWriter.write(sw, Collections.singletonList(tables.get(i)));
|
csvWriter.write(sw, Collections.singletonList(tables.get(i)));
|
||||||
|
|
||||||
String entryName = generateEntryName(baseName, pageNum, i + 1);
|
String entryName = generateEntryName(baseName, pageNum, i + 1);
|
||||||
csvEntries.add(new CsvEntry(entryName, sw.toString()));
|
csvEntries.add(new CsvEntry(entryName, sw.toString()));
|
||||||
}
|
}
|
||||||
@@ -83,7 +84,8 @@ public class ExtractCSVController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<byte[]> createZipResponse(List<CsvEntry> entries, String baseName) throws IOException {
|
private ResponseEntity<byte[]> createZipResponse(List<CsvEntry> entries, String baseName)
|
||||||
|
throws IOException {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
try (ZipOutputStream zipOut = new ZipOutputStream(baos)) {
|
try (ZipOutputStream zipOut = new ZipOutputStream(baos)) {
|
||||||
for (CsvEntry entry : entries) {
|
for (CsvEntry entry : entries) {
|
||||||
@@ -93,21 +95,25 @@ public class ExtractCSVController {
|
|||||||
zipOut.closeEntry();
|
zipOut.closeEntry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setContentDisposition(ContentDisposition.builder("attachment")
|
headers.setContentDisposition(
|
||||||
.filename(baseName + "_extracted.zip").build());
|
ContentDisposition.builder("attachment")
|
||||||
|
.filename(baseName + "_extracted.zip")
|
||||||
|
.build());
|
||||||
headers.setContentType(MediaType.parseMediaType("application/zip"));
|
headers.setContentType(MediaType.parseMediaType("application/zip"));
|
||||||
|
|
||||||
return ResponseEntity.ok().headers(headers).body(baos.toByteArray());
|
return ResponseEntity.ok().headers(headers).body(baos.toByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<String> createCsvResponse(CsvEntry entry, String baseName) {
|
private ResponseEntity<String> createCsvResponse(CsvEntry entry, String baseName) {
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setContentDisposition(ContentDisposition.builder("attachment")
|
headers.setContentDisposition(
|
||||||
.filename(baseName + "_extracted.csv").build());
|
ContentDisposition.builder("attachment")
|
||||||
|
.filename(baseName + "_extracted.csv")
|
||||||
|
.build());
|
||||||
headers.setContentType(MediaType.parseMediaType("text/csv"));
|
headers.setContentType(MediaType.parseMediaType("text/csv"));
|
||||||
|
|
||||||
return ResponseEntity.ok().headers(headers).body(entry.content());
|
return ResponseEntity.ok().headers(headers).body(entry.content());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.ExtractHeaderRequest;
|
import stirling.software.SPDF.model.api.misc.ExtractHeaderRequest;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest;
|
import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.RemoveBlankPagesRequest;
|
import stirling.software.SPDF.model.api.misc.RemoveBlankPagesRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
|
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
@@ -51,7 +52,7 @@ public class CompressController {
|
|||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void compressImagesInPDF(Path pdfFile, double initialScaleFactor) throws Exception {
|
private void compressImagesInPDF(Path pdfFile, double initialScaleFactor, boolean grayScale) throws Exception {
|
||||||
byte[] fileBytes = Files.readAllBytes(pdfFile);
|
byte[] fileBytes = Files.readAllBytes(pdfFile);
|
||||||
try (PDDocument doc = Loader.loadPDF(fileBytes)) {
|
try (PDDocument doc = Loader.loadPDF(fileBytes)) {
|
||||||
double scaleFactor = initialScaleFactor;
|
double scaleFactor = initialScaleFactor;
|
||||||
@@ -76,11 +77,23 @@ public class CompressController {
|
|||||||
bufferedImage.getScaledInstance(
|
bufferedImage.getScaledInstance(
|
||||||
newWidth, newHeight, Image.SCALE_SMOOTH);
|
newWidth, newHeight, Image.SCALE_SMOOTH);
|
||||||
|
|
||||||
BufferedImage scaledBufferedImage =
|
BufferedImage scaledBufferedImage;
|
||||||
new BufferedImage(
|
if (grayScale
|
||||||
newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
|
|| bufferedImage.getType() == BufferedImage.TYPE_BYTE_GRAY) {
|
||||||
scaledBufferedImage.getGraphics().drawImage(scaledImage, 0, 0, null);
|
scaledBufferedImage =
|
||||||
|
new BufferedImage(
|
||||||
|
newWidth, newHeight, BufferedImage.TYPE_BYTE_GRAY);
|
||||||
|
scaledBufferedImage
|
||||||
|
.getGraphics()
|
||||||
|
.drawImage(scaledImage, 0, 0, null);
|
||||||
|
} else {
|
||||||
|
scaledBufferedImage =
|
||||||
|
new BufferedImage(
|
||||||
|
newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
|
||||||
|
scaledBufferedImage
|
||||||
|
.getGraphics()
|
||||||
|
.drawImage(scaledImage, 0, 0, null);
|
||||||
|
}
|
||||||
ByteArrayOutputStream compressedImageStream =
|
ByteArrayOutputStream compressedImageStream =
|
||||||
new ByteArrayOutputStream();
|
new ByteArrayOutputStream();
|
||||||
ImageIO.write(scaledBufferedImage, "jpeg", compressedImageStream);
|
ImageIO.write(scaledBufferedImage, "jpeg", compressedImageStream);
|
||||||
@@ -139,6 +152,7 @@ public class CompressController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean sizeMet = false;
|
boolean sizeMet = false;
|
||||||
|
boolean grayscaleEnabled = Boolean.TRUE.equals(request.getGrayscale());
|
||||||
while (!sizeMet && optimizeLevel <= 9) {
|
while (!sizeMet && optimizeLevel <= 9) {
|
||||||
|
|
||||||
// Apply additional image compression for levels 6-9
|
// Apply additional image compression for levels 6-9
|
||||||
@@ -152,7 +166,7 @@ public class CompressController {
|
|||||||
case 9 -> 0.5; // 60% of original size
|
case 9 -> 0.5; // 60% of original size
|
||||||
default -> 1.0;
|
default -> 1.0;
|
||||||
};
|
};
|
||||||
compressImagesInPDF(tempInputFile, scaleFactor);
|
compressImagesInPDF(tempInputFile, scaleFactor, grayscaleEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run QPDF optimization
|
// Run QPDF optimization
|
||||||
@@ -169,6 +183,7 @@ public class CompressController {
|
|||||||
command.add("--compression-level=" + optimizeLevel);
|
command.add("--compression-level=" + optimizeLevel);
|
||||||
command.add("--compress-streams=y");
|
command.add("--compress-streams=y");
|
||||||
command.add("--object-streams=generate");
|
command.add("--object-streams=generate");
|
||||||
|
command.add("--no-warn");
|
||||||
command.add(tempInputFile.toString());
|
command.add(tempInputFile.toString());
|
||||||
command.add(tempOutputFile.toString());
|
command.add(tempOutputFile.toString());
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.ExtractImageScansRequest;
|
import stirling.software.SPDF.model.api.misc.ExtractImageScansRequest;
|
||||||
import stirling.software.SPDF.utils.CheckProgramInstall;
|
import stirling.software.SPDF.utils.CheckProgramInstall;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFExtractImagesRequest;
|
import stirling.software.SPDF.model.api.PDFExtractImagesRequest;
|
||||||
import stirling.software.SPDF.utils.ImageProcessingUtils;
|
import stirling.software.SPDF.utils.ImageProcessingUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.FlattenRequest;
|
import stirling.software.SPDF.model.api.misc.FlattenRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.MetadataRequest;
|
import stirling.software.SPDF.model.api.misc.MetadataRequest;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
import stirling.software.SPDF.utils.propertyeditor.StringToMapPropertyEditor;
|
import stirling.software.SPDF.utils.propertyeditor.StringToMapPropertyEditor;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.api.misc.ProcessPdfWithOcrRequest;
|
import stirling.software.SPDF.model.api.misc.ProcessPdfWithOcrRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.OverlayImageRequest;
|
import stirling.software.SPDF.model.api.misc.OverlayImageRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.PrintFileRequest;
|
import stirling.software.SPDF.model.api.misc.PrintFileRequest;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ import com.fasterxml.jackson.databind.JsonNode;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.SPDFApplication;
|
import stirling.software.SPDF.SPDFApplication;
|
||||||
import stirling.software.SPDF.model.ApiEndpoint;
|
import stirling.software.SPDF.model.ApiEndpoint;
|
||||||
import stirling.software.SPDF.model.Role;
|
import stirling.software.SPDF.model.Role;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.PipelineConfig;
|
import stirling.software.SPDF.model.PipelineConfig;
|
||||||
import stirling.software.SPDF.model.PipelineResult;
|
import stirling.software.SPDF.model.PipelineResult;
|
||||||
import stirling.software.SPDF.model.api.HandleDataRequest;
|
import stirling.software.SPDF.model.api.HandleDataRequest;
|
||||||
|
|||||||
@@ -5,9 +5,14 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.FileSystemException;
|
||||||
|
import java.nio.file.FileVisitResult;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.SimpleFileVisitor;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
@@ -24,7 +29,8 @@ import org.springframework.stereotype.Service;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
|
||||||
|
import stirling.software.SPDF.config.RuntimePathConfig;
|
||||||
import stirling.software.SPDF.model.PipelineConfig;
|
import stirling.software.SPDF.model.PipelineConfig;
|
||||||
import stirling.software.SPDF.model.PipelineOperation;
|
import stirling.software.SPDF.model.PipelineOperation;
|
||||||
import stirling.software.SPDF.model.PipelineResult;
|
import stirling.software.SPDF.model.PipelineResult;
|
||||||
@@ -50,18 +56,19 @@ public class PipelineDirectoryProcessor {
|
|||||||
ObjectMapper objectMapper,
|
ObjectMapper objectMapper,
|
||||||
ApiDocService apiDocService,
|
ApiDocService apiDocService,
|
||||||
PipelineProcessor processor,
|
PipelineProcessor processor,
|
||||||
FileMonitor fileMonitor) {
|
FileMonitor fileMonitor,
|
||||||
|
RuntimePathConfig runtimePathConfig) {
|
||||||
this.objectMapper = objectMapper;
|
this.objectMapper = objectMapper;
|
||||||
this.apiDocService = apiDocService;
|
this.apiDocService = apiDocService;
|
||||||
this.watchedFoldersDir = InstallationPathConfig.getPipelineWatchedFoldersDir();
|
this.watchedFoldersDir = runtimePathConfig.getPipelineWatchedFoldersPath();
|
||||||
this.finishedFoldersDir = InstallationPathConfig.getPipelineFinishedFoldersDir();
|
this.finishedFoldersDir = runtimePathConfig.getPipelineFinishedFoldersPath();
|
||||||
this.processor = processor;
|
this.processor = processor;
|
||||||
this.fileMonitor = fileMonitor;
|
this.fileMonitor = fileMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(fixedRate = 60000)
|
@Scheduled(fixedRate = 60000)
|
||||||
public void scanFolders() {
|
public void scanFolders() {
|
||||||
Path watchedFolderPath = Paths.get(watchedFoldersDir);
|
Path watchedFolderPath = Paths.get(watchedFoldersDir).toAbsolutePath();
|
||||||
if (!Files.exists(watchedFolderPath)) {
|
if (!Files.exists(watchedFolderPath)) {
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(watchedFolderPath);
|
Files.createDirectories(watchedFolderPath);
|
||||||
@@ -71,19 +78,33 @@ public class PipelineDirectoryProcessor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try (Stream<Path> paths = Files.walk(watchedFolderPath)) {
|
|
||||||
paths.filter(Files::isDirectory)
|
try {
|
||||||
.forEach(
|
Files.walkFileTree(
|
||||||
t -> {
|
watchedFolderPath,
|
||||||
try {
|
new SimpleFileVisitor<>() {
|
||||||
if (!t.equals(watchedFolderPath) && !t.endsWith("processing")) {
|
@Override
|
||||||
handleDirectory(t);
|
public FileVisitResult preVisitDirectory(
|
||||||
}
|
Path dir, BasicFileAttributes attrs) {
|
||||||
} catch (Exception e) {
|
try {
|
||||||
log.error("Error handling directory: {}", t, e);
|
// Skip root directory and "processing" subdirectories
|
||||||
|
if (!dir.equals(watchedFolderPath) && !dir.endsWith("processing")) {
|
||||||
|
handleDirectory(dir);
|
||||||
}
|
}
|
||||||
});
|
} catch (Exception e) {
|
||||||
} catch (Exception e) {
|
log.error("Error handling directory: {}", dir, e);
|
||||||
|
}
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFileFailed(Path path, IOException exc) {
|
||||||
|
// Handle broken symlinks or inaccessible directories
|
||||||
|
log.error("Error accessing path: {}", path, exc);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
log.error("Error walking through directory: {}", watchedFolderPath, e);
|
log.error("Error walking through directory: {}", watchedFolderPath, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,6 +208,7 @@ public class PipelineDirectoryProcessor {
|
|||||||
}
|
}
|
||||||
return isAllowed;
|
return isAllowed;
|
||||||
})
|
})
|
||||||
|
.map(Path::toAbsolutePath)
|
||||||
.filter(
|
.filter(
|
||||||
path -> {
|
path -> {
|
||||||
boolean isReady =
|
boolean isReady =
|
||||||
@@ -200,7 +222,10 @@ public class PipelineDirectoryProcessor {
|
|||||||
})
|
})
|
||||||
.map(Path::toFile)
|
.map(Path::toFile)
|
||||||
.toArray(File[]::new);
|
.toArray(File[]::new);
|
||||||
log.info("Collected {} files for processing", files.length);
|
log.info(
|
||||||
|
"Collected {} files for processing for {}",
|
||||||
|
files.length,
|
||||||
|
dir.toAbsolutePath().toString());
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,8 +235,35 @@ public class PipelineDirectoryProcessor {
|
|||||||
List<File> filesToProcess = new ArrayList<>();
|
List<File> filesToProcess = new ArrayList<>();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
Path targetPath = resolveUniqueFilePath(processingDir, file.getName());
|
Path targetPath = resolveUniqueFilePath(processingDir, file.getName());
|
||||||
Files.move(file.toPath(), targetPath);
|
|
||||||
filesToProcess.add(targetPath.toFile());
|
// Retry with exponential backoff
|
||||||
|
int maxRetries = 3;
|
||||||
|
int retryDelayMs = 500;
|
||||||
|
boolean moved = false;
|
||||||
|
|
||||||
|
for (int attempt = 1; attempt <= maxRetries; attempt++) {
|
||||||
|
try {
|
||||||
|
Files.move(file.toPath(), targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
moved = true;
|
||||||
|
break;
|
||||||
|
} catch (FileSystemException e) {
|
||||||
|
if (attempt < maxRetries) {
|
||||||
|
log.info("File move failed (attempt {}), retrying...", attempt);
|
||||||
|
try {
|
||||||
|
Thread.sleep(retryDelayMs * (int) Math.pow(2, attempt - 1));
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moved) {
|
||||||
|
filesToProcess.add(targetPath.toFile());
|
||||||
|
} else {
|
||||||
|
log.error("Failed to move file after {} attempts: {}", maxRetries, file.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return filesToProcess;
|
return filesToProcess;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ import io.github.pixee.security.Filenames;
|
|||||||
import io.github.pixee.security.ZipSecurity;
|
import io.github.pixee.security.ZipSecurity;
|
||||||
|
|
||||||
import jakarta.servlet.ServletContext;
|
import jakarta.servlet.ServletContext;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.SPDFApplication;
|
import stirling.software.SPDF.SPDFApplication;
|
||||||
import stirling.software.SPDF.model.PipelineConfig;
|
import stirling.software.SPDF.model.PipelineConfig;
|
||||||
import stirling.software.SPDF.model.PipelineOperation;
|
import stirling.software.SPDF.model.PipelineOperation;
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.security.SignPDFWithCertRequest;
|
import stirling.software.SPDF.model.api.security.SignPDFWithCertRequest;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFFile;
|
import stirling.software.SPDF.model.api.PDFFile;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.PDFText;
|
import stirling.software.SPDF.model.PDFText;
|
||||||
import stirling.software.SPDF.model.api.security.ManualRedactPdfRequest;
|
import stirling.software.SPDF.model.api.security.ManualRedactPdfRequest;
|
||||||
import stirling.software.SPDF.model.api.security.RedactPdfRequest;
|
import stirling.software.SPDF.model.api.security.RedactPdfRequest;
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
|
||||||
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
||||||
import stirling.software.SPDF.model.*;
|
import stirling.software.SPDF.model.*;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package stirling.software.SPDF.controller.web;
|
package stirling.software.SPDF.controller.web;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -15,14 +14,6 @@ import stirling.software.SPDF.utils.CheckProgramInstall;
|
|||||||
@Tag(name = "Convert", description = "Convert APIs")
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
public class ConverterWebController {
|
public class ConverterWebController {
|
||||||
|
|
||||||
@ConditionalOnExpression("${bookAndHtmlFormatsInstalled}")
|
|
||||||
@GetMapping("/book-to-pdf")
|
|
||||||
@Hidden
|
|
||||||
public String convertBookToPdfForm(Model model) {
|
|
||||||
model.addAttribute("currentPage", "book-to-pdf");
|
|
||||||
return "convert/book-to-pdf";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/img-to-pdf")
|
@GetMapping("/img-to-pdf")
|
||||||
@Hidden
|
@Hidden
|
||||||
public String convertImgToPdfForm(Model model) {
|
public String convertImgToPdfForm(Model model) {
|
||||||
@@ -67,14 +58,6 @@ public class ConverterWebController {
|
|||||||
|
|
||||||
// PDF TO......
|
// PDF TO......
|
||||||
|
|
||||||
@ConditionalOnExpression("${bookAndHtmlFormatsInstalled}")
|
|
||||||
@GetMapping("/pdf-to-book")
|
|
||||||
@Hidden
|
|
||||||
public String convertPdfToBookForm(Model model) {
|
|
||||||
model.addAttribute("currentPage", "pdf-to-book");
|
|
||||||
return "convert/pdf-to-book";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/pdf-to-img")
|
@GetMapping("/pdf-to-img")
|
||||||
@Hidden
|
@Hidden
|
||||||
public String pdfToimgForm(Model model) {
|
public String pdfToimgForm(Model model) {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.security.database.DatabaseService;
|
import stirling.software.SPDF.config.security.database.DatabaseService;
|
||||||
import stirling.software.SPDF.utils.FileInfo;
|
import stirling.software.SPDF.utils.FileInfo;
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ import io.swagger.v3.oas.annotations.Hidden;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
|
import stirling.software.SPDF.config.RuntimePathConfig;
|
||||||
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
|
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
|
||||||
import stirling.software.SPDF.model.SignatureFile;
|
import stirling.software.SPDF.model.SignatureFile;
|
||||||
import stirling.software.SPDF.service.SignatureService;
|
import stirling.software.SPDF.service.SignatureService;
|
||||||
@@ -38,14 +40,17 @@ public class GeneralWebController {
|
|||||||
private final SignatureService signatureService;
|
private final SignatureService signatureService;
|
||||||
private final UserServiceInterface userService;
|
private final UserServiceInterface userService;
|
||||||
private final ResourceLoader resourceLoader;
|
private final ResourceLoader resourceLoader;
|
||||||
|
private final RuntimePathConfig runtimePathConfig;
|
||||||
|
|
||||||
public GeneralWebController(
|
public GeneralWebController(
|
||||||
SignatureService signatureService,
|
SignatureService signatureService,
|
||||||
@Autowired(required = false) UserServiceInterface userService,
|
@Autowired(required = false) UserServiceInterface userService,
|
||||||
ResourceLoader resourceLoader) {
|
ResourceLoader resourceLoader,
|
||||||
|
RuntimePathConfig runtimePathConfig) {
|
||||||
this.signatureService = signatureService;
|
this.signatureService = signatureService;
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.resourceLoader = resourceLoader;
|
this.resourceLoader = resourceLoader;
|
||||||
|
this.runtimePathConfig = runtimePathConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/pipeline")
|
@GetMapping("/pipeline")
|
||||||
@@ -54,11 +59,9 @@ public class GeneralWebController {
|
|||||||
model.addAttribute("currentPage", "pipeline");
|
model.addAttribute("currentPage", "pipeline");
|
||||||
List<String> pipelineConfigs = new ArrayList<>();
|
List<String> pipelineConfigs = new ArrayList<>();
|
||||||
List<Map<String, String>> pipelineConfigsWithNames = new ArrayList<>();
|
List<Map<String, String>> pipelineConfigsWithNames = new ArrayList<>();
|
||||||
if (new File(InstallationPathConfig.getPipelineDefaultWebUIConfigsDir()).exists()) {
|
if (new File(runtimePathConfig.getPipelineDefaultWebUiConfigs()).exists()) {
|
||||||
try (Stream<Path> paths =
|
try (Stream<Path> paths =
|
||||||
Files.walk(
|
Files.walk(Paths.get(runtimePathConfig.getPipelineDefaultWebUiConfigs()))) {
|
||||||
Paths.get(
|
|
||||||
InstallationPathConfig.getPipelineDefaultWebUIConfigsDir()))) {
|
|
||||||
List<Path> jsonFiles =
|
List<Path> jsonFiles =
|
||||||
paths.filter(Files::isRegularFile)
|
paths.filter(Files::isRegularFile)
|
||||||
.filter(p -> p.toString().endsWith(".json"))
|
.filter(p -> p.toString().endsWith(".json"))
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import io.swagger.v3.oas.annotations.Hidden;
|
import io.swagger.v3.oas.annotations.Hidden;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.Dependency;
|
import stirling.software.SPDF.model.Dependency;
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ import io.swagger.v3.oas.annotations.Parameter;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.StartupApplicationListener;
|
import stirling.software.SPDF.config.StartupApplicationListener;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
import stirling.software.SPDF.config.YamlPropertySourceFactory;
|
import stirling.software.SPDF.config.YamlPropertySourceFactory;
|
||||||
import stirling.software.SPDF.model.provider.GithubProvider;
|
import stirling.software.SPDF.model.provider.GithubProvider;
|
||||||
@@ -285,6 +286,26 @@ public class ApplicationProperties {
|
|||||||
private String enableAnalytics;
|
private String enableAnalytics;
|
||||||
private Datasource datasource;
|
private Datasource datasource;
|
||||||
private Boolean disableSanitize;
|
private Boolean disableSanitize;
|
||||||
|
private CustomPaths customPaths = new CustomPaths();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class CustomPaths {
|
||||||
|
private Pipeline pipeline = new Pipeline();
|
||||||
|
private Operations operations = new Operations();
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Pipeline {
|
||||||
|
private String watchedFoldersDir;
|
||||||
|
private String finishedFoldersDir;
|
||||||
|
private String webUIConfigsDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Operations {
|
||||||
|
private String weasyprint;
|
||||||
|
private String unoconvert;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.util.Date;
|
|||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import lombok.Data;
|
|||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFFile;
|
import stirling.software.SPDF.model.api.PDFFile;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFFile;
|
import stirling.software.SPDF.model.api.PDFFile;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user