Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a8e47898e | ||
|
|
34316ec6c9 | ||
|
|
d7e590f24e |
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(chmod:*)",
|
||||||
|
"Bash(mkdir:*)",
|
||||||
|
"Bash(./gradlew:*)",
|
||||||
|
"Bash(grep:*)",
|
||||||
|
"Bash(cat:*)",
|
||||||
|
"Bash(find:*)",
|
||||||
|
"Bash(npm test)",
|
||||||
|
"Bash(npm test:*)",
|
||||||
|
"Bash(ls:*)",
|
||||||
|
"Bash(npx tsc:*)",
|
||||||
|
"Bash(node:*)",
|
||||||
|
"Bash(npm run dev:*)",
|
||||||
|
"Bash(sed:*)",
|
||||||
|
"Bash(npm run typecheck:*)"
|
||||||
|
],
|
||||||
|
"deny": [],
|
||||||
|
"defaultMode": "acceptEdits"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,15 +3,7 @@ name: Auto PR V2 Deployment
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [opened, synchronize, reopened, closed]
|
types: [opened, synchronize, reopened, closed]
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
pr:
|
|
||||||
description: "PR number to deploy"
|
|
||||||
required: true
|
|
||||||
allow_fork:
|
|
||||||
description: "Allow deploying fork PR?"
|
|
||||||
required: false
|
|
||||||
default: "false"
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -20,93 +12,102 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-pr:
|
check-pr:
|
||||||
if: (github.event_name == 'pull_request' && github.event.action != 'closed') || github.event_name == 'workflow_dispatch'
|
if: github.event.action != 'closed'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
should_deploy: ${{ steps.decide.outputs.should_deploy }}
|
should_deploy: ${{ steps.check-conditions.outputs.should_deploy }}
|
||||||
is_fork: ${{ steps.resolve.outputs.is_fork }}
|
pr_number: ${{ github.event.number }}
|
||||||
allow_fork: ${{ steps.decide.outputs.allow_fork }}
|
pr_repository: ${{ steps.get-pr-info.outputs.repository }}
|
||||||
pr_number: ${{ steps.resolve.outputs.pr_number }}
|
pr_ref: ${{ steps.get-pr-info.outputs.ref }}
|
||||||
pr_repository: ${{ steps.resolve.outputs.repository }}
|
|
||||||
pr_ref: ${{ steps.resolve.outputs.ref }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
|
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Resolve PR info
|
- name: Check deployment conditions
|
||||||
id: resolve
|
id: check-conditions
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const { owner, repo } = context.repo;
|
|
||||||
let prNumber = context.eventName === 'workflow_dispatch'
|
|
||||||
? parseInt(process.env.INPUT_PR, 10)
|
|
||||||
: context.payload.number;
|
|
||||||
|
|
||||||
if (!Number.isInteger(prNumber)) { core.setFailed('Invalid PR number'); return; }
|
|
||||||
|
|
||||||
const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber });
|
|
||||||
core.setOutput('pr_number', String(prNumber));
|
|
||||||
core.setOutput('repository', pr.head.repo.full_name);
|
|
||||||
core.setOutput('ref', pr.head.ref);
|
|
||||||
core.setOutput('is_fork', String(pr.head.repo.fork));
|
|
||||||
core.setOutput('base_ref', pr.base.ref);
|
|
||||||
core.setOutput('author', pr.user.login);
|
|
||||||
core.setOutput('state', pr.state);
|
|
||||||
|
|
||||||
- name: Decide deploy
|
|
||||||
id: decide
|
|
||||||
shell: bash
|
|
||||||
env:
|
env:
|
||||||
EVENT_NAME: ${{ github.event_name }}
|
|
||||||
STATE: ${{ steps.resolve.outputs.state }}
|
|
||||||
IS_FORK: ${{ steps.resolve.outputs.is_fork }}
|
|
||||||
# nur bei workflow_dispatch gesetzt:
|
|
||||||
ALLOW_FORK_INPUT: ${{ inputs.allow_fork }}
|
|
||||||
# für Auto-PR-Logik:
|
|
||||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||||
|
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
||||||
PR_BRANCH: ${{ github.event.pull_request.head.ref }}
|
PR_BRANCH: ${{ github.event.pull_request.head.ref }}
|
||||||
PR_BASE: ${{ steps.resolve.outputs.base_ref }}
|
|
||||||
PR_AUTHOR: ${{ steps.resolve.outputs.author }}
|
|
||||||
run: |
|
run: |
|
||||||
set -e
|
echo "PR Title: $PR_TITLE"
|
||||||
# Standard: nichts deployen
|
echo "PR Author: $PR_AUTHOR"
|
||||||
should=false
|
echo "PR Branch: $PR_BRANCH"
|
||||||
allow_fork="$(echo "${ALLOW_FORK_INPUT:-false}" | tr '[:upper:]' '[:lower:]')"
|
echo "PR Base Branch: ${{ github.event.pull_request.base.ref }}"
|
||||||
|
|
||||||
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
|
# Define authorized users
|
||||||
if [ "$STATE" != "open" ]; then
|
authorized_users=(
|
||||||
echo "PR not open -> skip"
|
"Frooodle"
|
||||||
else
|
"sf298"
|
||||||
if [ "$IS_FORK" = "true" ] && [ "$allow_fork" != "true" ]; then
|
"Ludy87"
|
||||||
echo "Fork PR and allow_fork=false -> skip"
|
"LaserKaspar"
|
||||||
else
|
"sbplat"
|
||||||
should=true
|
"reecebrowne"
|
||||||
fi
|
"DarioGii"
|
||||||
|
"ConnorYoh"
|
||||||
|
"EthanHealy01"
|
||||||
|
"jbrunton96"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if author is in the authorized list
|
||||||
|
is_authorized=false
|
||||||
|
for user in "${authorized_users[@]}"; do
|
||||||
|
if [[ "$PR_AUTHOR" == "$user" ]]; then
|
||||||
|
is_authorized=true
|
||||||
|
break
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# If PR is targeting V2 and user is authorized, deploy unconditionally
|
||||||
|
PR_BASE_BRANCH="${{ github.event.pull_request.base.ref }}"
|
||||||
|
if [[ "$PR_BASE_BRANCH" == "V2" && "$is_authorized" == "true" ]]; then
|
||||||
|
echo "✅ Deployment forced: PR targets V2 and author is authorized."
|
||||||
|
echo "should_deploy=true" >> $GITHUB_OUTPUT
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Otherwise, continue with original keyword checks
|
||||||
|
has_v2_keyword=false
|
||||||
|
if [[ "$PR_TITLE" =~ [Vv]2 ]] || [[ "$PR_TITLE" =~ [Vv]ersion.?2 ]] || [[ "$PR_TITLE" =~ [Vv]ersion.?[Tt]wo ]]; then
|
||||||
|
has_v2_keyword=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
has_branch_keyword=false
|
||||||
|
if [[ "$PR_BRANCH" =~ [Vv]2 ]] || [[ "$PR_BRANCH" =~ [Rr]eact ]]; then
|
||||||
|
has_branch_keyword=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$is_authorized" == "true" && ( "$has_v2_keyword" == "true" || "$has_branch_keyword" == "true" ) ]]; then
|
||||||
|
echo "✅ Deployment conditions met"
|
||||||
|
echo "should_deploy=true" >> $GITHUB_OUTPUT
|
||||||
else
|
else
|
||||||
auth_users=("Frooodle" "sf298" "Ludy87" "LaserKaspar" "sbplat" "reecebrowne" "DarioGii" "ConnorYoh" "EthanHealy01" "jbrunton96")
|
echo "❌ Deployment conditions not met"
|
||||||
is_auth=false; for u in "${auth_users[@]}"; do [ "$u" = "$PR_AUTHOR" ] && is_auth=true && break; done
|
echo " - Authorized user: $is_authorized"
|
||||||
if [ "$PR_BASE" = "V2" ] && [ "$is_auth" = true ]; then
|
echo " - Has V2 keyword in title: $has_v2_keyword"
|
||||||
should=true
|
echo " - Has V2/React keyword in branch: $has_branch_keyword"
|
||||||
else
|
echo "should_deploy=false" >> $GITHUB_OUTPUT
|
||||||
title_has_v2=false; echo "$PR_TITLE" | grep -qiE 'v2|version.?2|version.?two' && title_has_v2=true
|
|
||||||
branch_has_kw=false; echo "$PR_BRANCH" | grep -qiE 'v2|react' && branch_has_kw=true
|
|
||||||
if [ "$is_auth" = true ] && { [ "$title_has_v2" = true ] || [ "$branch_has_kw" = true ]; }; then
|
|
||||||
should=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "should_deploy=$should" >> $GITHUB_OUTPUT
|
- name: Get PR repository and ref
|
||||||
echo "allow_fork=${allow_fork:-false}" >> $GITHUB_OUTPUT
|
id: get-pr-info
|
||||||
|
if: steps.check-conditions.outputs.should_deploy == 'true'
|
||||||
|
run: |
|
||||||
|
# For forks, use the full repository name, for internal PRs use the current repo
|
||||||
|
if [[ "${{ github.event.pull_request.head.repo.fork }}" == "true" ]]; then
|
||||||
|
repository="${{ github.event.pull_request.head.repo.full_name }}"
|
||||||
|
else
|
||||||
|
repository="${{ github.repository }}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "repository=$repository" >> $GITHUB_OUTPUT
|
||||||
|
echo "ref=${{ github.event.pull_request.head.ref }}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
deploy-v2-pr:
|
deploy-v2-pr:
|
||||||
needs: check-pr
|
needs: check-pr
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: needs.check-pr.outputs.should_deploy == 'true' && (needs.check-pr.outputs.is_fork == 'false' || needs.check-pr.outputs.allow_fork == 'true')
|
if: needs.check-pr.outputs.should_deploy == 'true'
|
||||||
# Concurrency control - only one deployment per PR at a time
|
# Concurrency control - only one deployment per PR at a time
|
||||||
concurrency:
|
concurrency:
|
||||||
group: v2-deploy-pr-${{ needs.check-pr.outputs.pr_number }}
|
group: v2-deploy-pr-${{ needs.check-pr.outputs.pr_number }}
|
||||||
@@ -118,7 +119,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
|
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
@@ -153,13 +154,13 @@ jobs:
|
|||||||
issue_number: prNumber,
|
issue_number: prNumber,
|
||||||
per_page: 100
|
per_page: 100
|
||||||
});
|
});
|
||||||
|
|
||||||
const v2Comments = comments.filter(comment =>
|
const v2Comments = comments.filter(comment =>
|
||||||
comment.body.includes('🚀 **Auto-deploying V2 version**') ||
|
comment.body.includes('🚀 **Auto-deploying V2 version**') ||
|
||||||
comment.body.includes('## 🚀 V2 Auto-Deployment Complete!') ||
|
comment.body.includes('## 🚀 V2 Auto-Deployment Complete!') ||
|
||||||
comment.body.includes('❌ **V2 Auto-deployment failed**')
|
comment.body.includes('❌ **V2 Auto-deployment failed**')
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const comment of v2Comments) {
|
for (const comment of v2Comments) {
|
||||||
console.log(`Deleting old V2 comment: ${comment.id}`);
|
console.log(`Deleting old V2 comment: ${comment.id}`);
|
||||||
await github.rest.issues.deleteComment({
|
await github.rest.issues.deleteComment({
|
||||||
@@ -176,6 +177,7 @@ jobs:
|
|||||||
issue_number: prNumber,
|
issue_number: prNumber,
|
||||||
body: `🚀 **Auto-deploying V2 version** for PR #${prNumber}...\n\n_This is an automated deployment triggered by V2/version2 keywords in the PR title or V2/React keywords in the branch name._\n\n⚠️ **Note:** If new commits are pushed during deployment, this build will be cancelled and replaced with the latest version.`
|
body: `🚀 **Auto-deploying V2 version** for PR #${prNumber}...\n\n_This is an automated deployment triggered by V2/version2 keywords in the PR title or V2/React keywords in the branch name._\n\n⚠️ **Note:** If new commits are pushed during deployment, this build will be cancelled and replaced with the latest version.`
|
||||||
});
|
});
|
||||||
|
|
||||||
return newComment.id;
|
return newComment.id;
|
||||||
|
|
||||||
- name: Checkout PR
|
- name: Checkout PR
|
||||||
@@ -186,6 +188,7 @@ jobs:
|
|||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
fetch-depth: 0 # Fetch full history for commit hash detection
|
fetch-depth: 0 # Fetch full history for commit hash detection
|
||||||
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
|
|
||||||
@@ -209,7 +212,7 @@ jobs:
|
|||||||
if [ -z "$FRONTEND_HASH" ]; then
|
if [ -z "$FRONTEND_HASH" ]; then
|
||||||
FRONTEND_HASH="no-frontend-changes"
|
FRONTEND_HASH="no-frontend-changes"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get last commit that touched backend code, docker/backend, or docker/compose
|
# Get last commit that touched backend code, docker/backend, or docker/compose
|
||||||
BACKEND_HASH=$(git log -1 --format="%H" -- app/ docker/backend/ docker/compose/ 2>/dev/null || echo "")
|
BACKEND_HASH=$(git log -1 --format="%H" -- app/ docker/backend/ docker/compose/ 2>/dev/null || echo "")
|
||||||
if [ -z "$BACKEND_HASH" ]; then
|
if [ -z "$BACKEND_HASH" ]; then
|
||||||
@@ -318,7 +321,7 @@ jobs:
|
|||||||
SWAGGER_SERVER_URL: "https://${V2_PORT}.ssl.stirlingpdf.cloud"
|
SWAGGER_SERVER_URL: "https://${V2_PORT}.ssl.stirlingpdf.cloud"
|
||||||
baseUrl: "https://${V2_PORT}.ssl.stirlingpdf.cloud"
|
baseUrl: "https://${V2_PORT}.ssl.stirlingpdf.cloud"
|
||||||
restart: on-failure:5
|
restart: on-failure:5
|
||||||
|
|
||||||
stirling-pdf-v2-frontend:
|
stirling-pdf-v2-frontend:
|
||||||
container_name: stirling-pdf-v2-frontend-pr-${{ needs.check-pr.outputs.pr_number }}
|
container_name: stirling-pdf-v2-frontend-pr-${{ needs.check-pr.outputs.pr_number }}
|
||||||
image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }}
|
image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }}
|
||||||
@@ -351,7 +354,7 @@ jobs:
|
|||||||
|
|
||||||
# Clean up unused Docker resources to save space
|
# Clean up unused Docker resources to save space
|
||||||
docker system prune -af --volumes || true
|
docker system prune -af --volumes || true
|
||||||
|
|
||||||
# Clean up old backend/frontend images (older than 2 weeks)
|
# Clean up old backend/frontend images (older than 2 weeks)
|
||||||
docker image prune -af --filter "until=336h" --filter "label!=keep=true" || true
|
docker image prune -af --filter "until=336h" --filter "label!=keep=true" || true
|
||||||
ENDSSH
|
ENDSSH
|
||||||
@@ -489,7 +492,7 @@ jobs:
|
|||||||
|
|
||||||
# Clean up old unused images (older than 2 weeks) but keep recent ones for reuse
|
# Clean up old unused images (older than 2 weeks) but keep recent ones for reuse
|
||||||
docker image prune -af --filter "until=336h" --filter "label!=keep=true" || true
|
docker image prune -af --filter "until=336h" --filter "label!=keep=true" || true
|
||||||
|
|
||||||
# Note: We don't remove the commit-based images since they can be reused across PRs
|
# Note: We don't remove the commit-based images since they can be reused across PRs
|
||||||
# Only remove PR-specific containers and directories
|
# Only remove PR-specific containers and directories
|
||||||
ENDSSH
|
ENDSSH
|
||||||
@@ -498,4 +501,5 @@ jobs:
|
|||||||
if: always()
|
if: always()
|
||||||
run: |
|
run: |
|
||||||
rm -f ../private.key
|
rm -f ../private.key
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
|
|||||||
@@ -32,29 +32,18 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Checkout PR head (default)
|
- name: Check out code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Setup GitHub App Bot
|
- name: Setup GitHub App Bot
|
||||||
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false)
|
|
||||||
id: setup-bot
|
id: setup-bot
|
||||||
uses: ./.github/actions/setup-bot
|
uses: ./.github/actions/setup-bot
|
||||||
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 }}
|
||||||
|
|
||||||
- name: Checkout BASE branch (safe script)
|
|
||||||
if: github.event_name == 'pull_request'
|
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.base.sha }}
|
|
||||||
path: base
|
|
||||||
fetch-depth: 1
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||||
with:
|
with:
|
||||||
@@ -64,45 +53,12 @@ jobs:
|
|||||||
|
|
||||||
- name: Install frontend dependencies
|
- name: Install frontend dependencies
|
||||||
working-directory: frontend
|
working-directory: frontend
|
||||||
env:
|
run: npm ci
|
||||||
NPM_CONFIG_IGNORE_SCRIPTS: "true"
|
|
||||||
run: npm ci --ignore-scripts --audit=false --fund=false
|
|
||||||
|
|
||||||
- name: Generate frontend license report (internal PR)
|
- name: Generate frontend license report
|
||||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false
|
|
||||||
working-directory: frontend
|
working-directory: frontend
|
||||||
env:
|
|
||||||
PR_IS_FORK: "false"
|
|
||||||
run: npm run generate-licenses
|
run: npm run generate-licenses
|
||||||
|
|
||||||
- name: Generate frontend license report (fork PRs, pinned)
|
|
||||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true
|
|
||||||
env:
|
|
||||||
NPM_CONFIG_IGNORE_SCRIPTS: "true"
|
|
||||||
working-directory: frontend
|
|
||||||
run: |
|
|
||||||
mkdir -p src/assets
|
|
||||||
npx --yes license-report --only=prod --output=json > src/assets/3rdPartyLicenses.json
|
|
||||||
|
|
||||||
- name: Postprocess with project script (BASE version)
|
|
||||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true
|
|
||||||
env:
|
|
||||||
PR_IS_FORK: "true"
|
|
||||||
run: |
|
|
||||||
node base/frontend/scripts/generate-licenses.js \
|
|
||||||
--input frontend/src/assets/3rdPartyLicenses.json
|
|
||||||
|
|
||||||
- name: Copy postprocessed artifacts back (fork PRs)
|
|
||||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true
|
|
||||||
run: |
|
|
||||||
mkdir -p frontend/src/assets
|
|
||||||
if [ -f "base/frontend/src/assets/3rdPartyLicenses.json" ]; then
|
|
||||||
cp base/frontend/src/assets/3rdPartyLicenses.json frontend/src/assets/3rdPartyLicenses.json
|
|
||||||
fi
|
|
||||||
if [ -f "base/frontend/src/assets/license-warnings.json" ]; then
|
|
||||||
cp base/frontend/src/assets/license-warnings.json frontend/src/assets/license-warnings.json
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Check for license warnings
|
- name: Check for license warnings
|
||||||
run: |
|
run: |
|
||||||
if [ -f "frontend/src/assets/license-warnings.json" ]; then
|
if [ -f "frontend/src/assets/license-warnings.json" ]; then
|
||||||
@@ -113,7 +69,7 @@ jobs:
|
|||||||
|
|
||||||
# PR Event: Check licenses and comment on PR
|
# PR Event: Check licenses and comment on PR
|
||||||
- name: Delete previous license check comments
|
- name: Delete previous license check comments
|
||||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false
|
if: github.event_name == 'pull_request'
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
with:
|
with:
|
||||||
github-token: ${{ steps.setup-bot.outputs.token }}
|
github-token: ${{ steps.setup-bot.outputs.token }}
|
||||||
@@ -145,28 +101,8 @@ jobs:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- name: Summarize results (fork PRs)
|
|
||||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true
|
|
||||||
run: |
|
|
||||||
{
|
|
||||||
echo "## Frontend License Check"
|
|
||||||
echo ""
|
|
||||||
if [ "${LICENSE_WARNINGS_EXIST}" = "true" ]; then
|
|
||||||
echo "❌ **Failed** – incompatible or unknown licenses found."
|
|
||||||
if [ -f "frontend/src/assets/license-warnings.json" ]; then
|
|
||||||
echo ""
|
|
||||||
echo "### Warnings"
|
|
||||||
jq -r '.warnings[] | "- \(.message)"' frontend/src/assets/license-warnings.json || true
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "✅ **Passed** – no license warnings detected."
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
echo "_Note: This is a fork PR. PR comments are disabled; use this summary._"
|
|
||||||
} >> "$GITHUB_STEP_SUMMARY"
|
|
||||||
|
|
||||||
- name: Comment on PR - License Check Results
|
- name: Comment on PR - License Check Results
|
||||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false
|
if: github.event_name == 'pull_request'
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||||
with:
|
with:
|
||||||
github-token: ${{ steps.setup-bot.outputs.token }}
|
github-token: ${{ steps.setup-bot.outputs.token }}
|
||||||
|
|||||||
@@ -203,10 +203,3 @@ id_ed25519.pub
|
|||||||
|
|
||||||
# node_modules
|
# node_modules
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
# Translation temp files
|
|
||||||
*_compact.json
|
|
||||||
*compact*.json
|
|
||||||
test_batch.json
|
|
||||||
*.backup.*.json
|
|
||||||
frontend/public/locales/*/translation.backup*.json
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ Frontend designed for **stateful document processing**:
|
|||||||
#### FileContext - Central State Management
|
#### FileContext - Central State Management
|
||||||
**Location**: `src/contexts/FileContext.tsx`
|
**Location**: `src/contexts/FileContext.tsx`
|
||||||
- **Active files**: Currently loaded PDFs and their variants
|
- **Active files**: Currently loaded PDFs and their variants
|
||||||
- **Tool navigation**: Current mode (viewer/pageEditor/fileEditor/toolName)
|
- **Tool navigation**: Current mode (viewer/pageEditor/fileEditor/toolName)
|
||||||
- **Memory management**: PDF document cleanup, blob URL lifecycle, Web Worker management
|
- **Memory management**: PDF document cleanup, blob URL lifecycle, Web Worker management
|
||||||
- **IndexedDB persistence**: File storage with thumbnail caching
|
- **IndexedDB persistence**: File storage with thumbnail caching
|
||||||
- **Preview system**: Tools can preview results (e.g., Split → Viewer → back to Split) without context pollution
|
- **Preview system**: Tools can preview results (e.g., Split → Viewer → back to Split) without context pollution
|
||||||
@@ -89,6 +89,7 @@ return useToolOperation({
|
|||||||
endpoint: '/api/v1/misc/compress-pdf',
|
endpoint: '/api/v1/misc/compress-pdf',
|
||||||
buildFormData: (params, file: File) => { /* single file */ },
|
buildFormData: (params, file: File) => { /* single file */ },
|
||||||
multiFileEndpoint: false,
|
multiFileEndpoint: false,
|
||||||
|
filePrefix: 'compressed_'
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -102,7 +103,7 @@ return useToolOperation({
|
|||||||
endpoint: '/api/v1/general/split-pages',
|
endpoint: '/api/v1/general/split-pages',
|
||||||
buildFormData: (params, files: File[]) => { /* all files */ },
|
buildFormData: (params, files: File[]) => { /* all files */ },
|
||||||
multiFileEndpoint: true,
|
multiFileEndpoint: true,
|
||||||
filePrefix: 'split_',
|
filePrefix: 'split_'
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -114,12 +115,13 @@ return useToolOperation({
|
|||||||
return useToolOperation({
|
return useToolOperation({
|
||||||
operationType: 'convert',
|
operationType: 'convert',
|
||||||
customProcessor: async (params, files) => { /* custom logic */ },
|
customProcessor: async (params, files) => { /* custom logic */ },
|
||||||
|
filePrefix: 'converted_'
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
**Benefits**:
|
**Benefits**:
|
||||||
- **No Timeouts**: Operations run until completion (supports 100GB+ files)
|
- **No Timeouts**: Operations run until completion (supports 100GB+ files)
|
||||||
- **Consistent**: All tools follow same pattern and interface
|
- **Consistent**: All tools follow same pattern and interface
|
||||||
- **Maintainable**: Single responsibility hooks, easy to test and modify
|
- **Maintainable**: Single responsibility hooks, easy to test and modify
|
||||||
- **i18n Ready**: Built-in internationalization support
|
- **i18n Ready**: Built-in internationalization support
|
||||||
- **Type Safe**: Full TypeScript support with generic interfaces
|
- **Type Safe**: Full TypeScript support with generic interfaces
|
||||||
@@ -183,7 +185,7 @@ return useToolOperation({
|
|||||||
## Frontend Architecture Status
|
## Frontend Architecture Status
|
||||||
|
|
||||||
- **Core Status**: React SPA architecture complete with multi-tool workflow support
|
- **Core Status**: React SPA architecture complete with multi-tool workflow support
|
||||||
- **State Management**: FileContext handles all file operations and tool navigation
|
- **State Management**: FileContext handles all file operations and tool navigation
|
||||||
- **File Processing**: Production-ready with memory management for large PDF workflows (up to 100GB+)
|
- **File Processing**: Production-ready with memory management for large PDF workflows (up to 100GB+)
|
||||||
- **Tool Integration**: Modular hook architecture with `useToolOperation` orchestrator
|
- **Tool Integration**: Modular hook architecture with `useToolOperation` orchestrator
|
||||||
- Individual hooks: `useToolState`, `useToolApiCalls`, `useToolResources`
|
- Individual hooks: `useToolState`, `useToolApiCalls`, `useToolResources`
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import org.springframework.core.annotation.AliasFor;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut for a POST endpoint that is executed through the Stirling "auto‑job" framework.
|
* Shortcut for a POST endpoint that is executed through the Stirling "auto‑job" framework.
|
||||||
*
|
*
|
||||||
@@ -31,7 +29,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
|||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
@RequestMapping(method = RequestMethod.POST)
|
@RequestMapping(method = RequestMethod.POST)
|
||||||
@RequestBody(required = true)
|
|
||||||
public @interface AutoJobPostMapping {
|
public @interface AutoJobPostMapping {
|
||||||
|
|
||||||
/** Alias for {@link RequestMapping#value} – the path mapping of the endpoint. */
|
/** Alias for {@link RequestMapping#value} – the path mapping of the endpoint. */
|
||||||
|
|||||||
-48
@@ -1,48 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Account Security API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/account"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/account")
|
|
||||||
@Tag(
|
|
||||||
name = "Account Security",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Account security and protection services for user safety and organizational compliance.
|
|
||||||
|
|
||||||
This endpoint group provides account security capabilities for organizations requiring
|
|
||||||
enhanced protection against unauthorized access, security threats, and compliance violations.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Corporate security policy compliance and SOX, HIPAA, GDPR requirements
|
|
||||||
• Fraud prevention, identity theft protection, and account compromise recovery
|
|
||||||
• Multi-factor authentication implementation and insider threat mitigation
|
|
||||||
• Account recovery and emergency access procedures
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Enterprise risk management, security governance, and customer trust protection
|
|
||||||
• Legal liability reduction and insurance requirement fulfillment
|
|
||||||
• Audit preparation, compliance reporting, and business continuity management
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Security incident response, forensic investigation, and user training
|
|
||||||
• Emergency account lockdown, suspicious activity monitoring, and compliance documentation
|
|
||||||
|
|
||||||
Target users: Security administrators, compliance officers, and organizations
|
|
||||||
prioritizing account security and regulatory compliance.
|
|
||||||
""")
|
|
||||||
public @interface AccountSecurityApi {}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Admin Settings API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/admin/settings"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/admin/settings")
|
|
||||||
@Tag(
|
|
||||||
name = "Admin Settings",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
System administration and configuration management for enterprise deployments.
|
|
||||||
|
|
||||||
This endpoint group provides administrative control for organizations deploying
|
|
||||||
Stirling PDF in production environments with multi-user scenarios.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Enterprise deployment configuration and multi-tenant environment management
|
|
||||||
• Security policy enforcement, compliance monitoring, and capacity planning
|
|
||||||
• Operational maintenance, troubleshooting, and enterprise infrastructure integration
|
|
||||||
• Disaster recovery and business continuity preparation
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Corporate IT governance, policy enforcement, and compliance reporting
|
|
||||||
• Cost optimization, SLA monitoring, and vendor management oversight
|
|
||||||
• Risk management and security incident response
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• 24/7 production monitoring, scheduled maintenance, and system updates
|
|
||||||
• Emergency response, change management, and performance optimization
|
|
||||||
|
|
||||||
Target users: IT administrators, system engineers, and operations teams
|
|
||||||
responsible for enterprise-grade document processing infrastructure.
|
|
||||||
""")
|
|
||||||
public @interface AdminApi {}
|
|
||||||
-46
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Admin Server Certificate API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/admin/server-certificate"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/admin/server-certificate")
|
|
||||||
@Tag(
|
|
||||||
name = "Admin - Server Certificate",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Server certificate management for secure enterprise deployments and encrypted communications.
|
|
||||||
|
|
||||||
This endpoint group provides certificate lifecycle management for organizations
|
|
||||||
requiring secure communications in document processing infrastructure.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Corporate security compliance and encrypted communications for healthcare/finance
|
|
||||||
• Customer data protection, internal audits, and multi-environment standardization
|
|
||||||
• Third-party security assessments and disaster recovery security measures
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Enterprise security governance, client trust protection, and secure B2B exchange
|
|
||||||
• Legal requirement fulfillment, liability reduction, and M&A security preparation
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Certificate renewal, emergency replacement, and security incident response
|
|
||||||
• Multi-site deployment coordination and cloud migration preparation
|
|
||||||
|
|
||||||
Target users: Security administrators, compliance officers, and IT infrastructure
|
|
||||||
teams requiring enterprise-grade security for document processing systems.
|
|
||||||
""")
|
|
||||||
public @interface AdminServerCertificateApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Analysis API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/analysis"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/analysis")
|
|
||||||
@Tag(
|
|
||||||
name = "Analysis",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Document analysis and information extraction services for content intelligence and insights.
|
|
||||||
|
|
||||||
This endpoint group provides analytical capabilities to understand document structure,
|
|
||||||
extract information, and generate insights from PDF content for automated processing.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Document inventory management and content audit for compliance verification
|
|
||||||
• Quality assurance workflows and business intelligence analytics
|
|
||||||
• Migration planning, accessibility evaluation, and document forensics
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Legal discovery, financial document review, and healthcare records analysis
|
|
||||||
• Academic research, government processing, and publishing optimization
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Large-scale profiling, migration assessment, and performance optimization
|
|
||||||
• Automated quality control and content strategy development
|
|
||||||
|
|
||||||
Target users: Data analysts, QA teams, administrators, and business intelligence
|
|
||||||
professionals requiring detailed document insights.
|
|
||||||
""")
|
|
||||||
public @interface AnalysisApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Configuration API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/config"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/config")
|
|
||||||
@Tag(
|
|
||||||
name = "Config",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
System configuration management for deployment optimization and operational control.
|
|
||||||
|
|
||||||
This endpoint group provides system configuration capabilities for organizations
|
|
||||||
deploying and operating Stirling PDF in various environments.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Environment-specific deployment and performance tuning for varying workloads
|
|
||||||
• Resource optimization, cost management, and infrastructure integration
|
|
||||||
• Compliance configuration, disaster recovery, and multi-environment standardization
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Operational cost optimization, SLA compliance, and risk management
|
|
||||||
• Vendor integration, change management, and capacity planning
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• System deployment, performance troubleshooting, and emergency changes
|
|
||||||
• Planned maintenance and multi-site deployment coordination
|
|
||||||
|
|
||||||
Target users: System administrators, DevOps engineers, and IT operations teams
|
|
||||||
responsible for deployment configuration and system optimization.
|
|
||||||
""")
|
|
||||||
public @interface ConfigApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Convert API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/convert"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/convert")
|
|
||||||
@Tag(
|
|
||||||
name = "Convert",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Document format transformation services for cross-platform compatibility and workflow integration.
|
|
||||||
|
|
||||||
This endpoint group enables transformation between various formats, supporting
|
|
||||||
diverse business workflows and system integrations for mixed document ecosystems.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Legacy system integration, document migration, and cross-platform sharing
|
|
||||||
• Archive standardization, publishing preparation, and content adaptation
|
|
||||||
• Accessibility compliance and mobile-friendly document preparation
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Enterprise content management, digital publishing, and educational platforms
|
|
||||||
• Legal document processing, healthcare interoperability, and government standardization
|
|
||||||
|
|
||||||
Integration scenarios:
|
|
||||||
• API-driven pipelines, automated workflow preparation, and batch conversions
|
|
||||||
• Real-time format adaptation for user requests
|
|
||||||
|
|
||||||
Target users: System integrators, content managers, digital archivists, and
|
|
||||||
organizations requiring flexible document format interoperability.
|
|
||||||
""")
|
|
||||||
public @interface ConvertApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Database Management API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/database"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/database")
|
|
||||||
@Tag(
|
|
||||||
name = "Database",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Database operations for data protection and business continuity management.
|
|
||||||
|
|
||||||
This endpoint group provides essential database operations for organizations requiring
|
|
||||||
reliable data protection and recovery capabilities.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Regular data backup, disaster recovery, and business continuity planning
|
|
||||||
• System migration, compliance management, and development environment support
|
|
||||||
• Operational troubleshooting and scheduled maintenance operations
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Risk management, regulatory compliance, and operational resilience
|
|
||||||
• Data governance, change management, and quality assurance support
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Routine backup, emergency recovery, and system maintenance preparation
|
|
||||||
• Data migration projects and performance monitoring
|
|
||||||
|
|
||||||
Target users: Operations teams, system administrators, and organizations requiring
|
|
||||||
reliable data protection and operational database management.
|
|
||||||
""")
|
|
||||||
public @interface DatabaseApi {}
|
|
||||||
-46
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Database Management API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/admin/database"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/admin/database")
|
|
||||||
@Tag(
|
|
||||||
name = "Database Management",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Enterprise database administration for production data management and business continuity.
|
|
||||||
|
|
||||||
This endpoint group provides database administration capabilities for organizations
|
|
||||||
operating Stirling PDF in production environments.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Business continuity, disaster recovery, and regulatory compliance requirements
|
|
||||||
• Performance optimization, data security, and system migration projects
|
|
||||||
• Audit preparation, compliance reporting, and cost optimization
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Enterprise risk management, regulatory compliance, and SLA monitoring
|
|
||||||
• Data retention policies, security incident response, and vendor oversight
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Scheduled maintenance, emergency recovery, and capacity planning
|
|
||||||
• Performance troubleshooting and multi-environment deployment coordination
|
|
||||||
|
|
||||||
Target users: Database administrators, IT operations teams, and enterprise
|
|
||||||
administrators responsible for production data management and system reliability.
|
|
||||||
""")
|
|
||||||
public @interface DatabaseManagementApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Filter API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/filter"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/filter")
|
|
||||||
@Tag(
|
|
||||||
name = "Filter",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Document content filtering and search operations for information discovery and organization.
|
|
||||||
|
|
||||||
This endpoint group enables intelligent content discovery and organization within
|
|
||||||
document collections for content-based processing and information extraction.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Legal discovery, research organization, and compliance auditing
|
|
||||||
• Content moderation, academic research, and business intelligence
|
|
||||||
• Quality assurance and content validation workflows
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Contract analysis, financial review, and healthcare records organization
|
|
||||||
• Government processing, educational curation, and IP protection
|
|
||||||
|
|
||||||
Workflow scenarios:
|
|
||||||
• Large-scale processing, automated classification, and information extraction
|
|
||||||
• Document preparation for further processing or analysis
|
|
||||||
|
|
||||||
Target users: Legal professionals, researchers, compliance officers, and
|
|
||||||
organizations requiring intelligent document content discovery and organization.
|
|
||||||
""")
|
|
||||||
public @interface FilterApi {}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for General PDF processing API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/general"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/general")
|
|
||||||
@Tag(
|
|
||||||
name = "General",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Core PDF processing operations for fundamental document manipulation workflows.
|
|
||||||
|
|
||||||
This endpoint group provides essential PDF functionality that forms the foundation
|
|
||||||
of most document processing workflows across various industries.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Document preparation for archival systems and content organization
|
|
||||||
• File preparation for distribution, accessibility compliance, and batch processing
|
|
||||||
• Document consolidation for reporting and legal compliance workflows
|
|
||||||
|
|
||||||
Typical applications:
|
|
||||||
• Content management, publishing workflows, and educational content distribution
|
|
||||||
• Business process automation and archive management
|
|
||||||
|
|
||||||
Target users: Content managers, document processors, and organizations requiring
|
|
||||||
reliable foundational PDF manipulation capabilities.
|
|
||||||
""")
|
|
||||||
public @interface GeneralApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Info API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/info"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/info")
|
|
||||||
@Tag(
|
|
||||||
name = "Info",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
System information and operational insights for monitoring and performance management.
|
|
||||||
|
|
||||||
This endpoint group provides system information and operational metrics for organizations
|
|
||||||
operating Stirling PDF in production environments.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• System health monitoring, performance optimization, and capacity planning
|
|
||||||
• Troubleshooting, compliance monitoring, and SLA reporting
|
|
||||||
• Cost optimization, usage analysis, and security monitoring
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Operational cost management, business continuity monitoring, and vendor management
|
|
||||||
• Compliance reporting, strategic planning, and customer service tracking
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• 24/7 monitoring, scheduled maintenance, and emergency response coordination
|
|
||||||
• System upgrade planning and capacity scaling decisions
|
|
||||||
|
|
||||||
Target users: Operations teams, system administrators, and management teams requiring
|
|
||||||
operational insights and system performance visibility.
|
|
||||||
""")
|
|
||||||
public @interface InfoApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Miscellaneous API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/misc"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/misc")
|
|
||||||
@Tag(
|
|
||||||
name = "Misc",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Specialized utilities and supplementary tools for enhanced document processing workflows.
|
|
||||||
|
|
||||||
This endpoint group provides utility operations that support core document processing
|
|
||||||
tasks and address specific workflow needs in real-world scenarios.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Document optimization for bandwidth-limited environments and storage cost management
|
|
||||||
• Document repair, content extraction, and validation for quality assurance
|
|
||||||
• Accessibility improvement and custom processing for specialized needs
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Web publishing optimization, email attachment management, and archive efficiency
|
|
||||||
• Mobile compatibility, print production, and legacy document recovery
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Batch processing, quality control, and performance optimization
|
|
||||||
• Troubleshooting and recovery of problematic documents
|
|
||||||
|
|
||||||
Target users: System administrators, document specialists, and organizations requiring
|
|
||||||
specialized document processing and optimization tools.
|
|
||||||
""")
|
|
||||||
public @interface MiscApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Pipeline API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/pipeline"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/pipeline")
|
|
||||||
@Tag(
|
|
||||||
name = "Pipeline",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Automated document processing workflows for complex multi-stage business operations.
|
|
||||||
|
|
||||||
This endpoint group enables organizations to create sophisticated document processing
|
|
||||||
workflows that combine multiple operations into streamlined, repeatable processes.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Invoice processing, legal document review, and healthcare records standardization
|
|
||||||
• Government processing, educational content preparation, and publishing automation
|
|
||||||
• Contract lifecycle management and approval processes
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Automated compliance reporting, large-scale migration, and quality assurance
|
|
||||||
• Archive preparation, content delivery, and document approval workflows
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Scheduled batch processing and event-driven document processing
|
|
||||||
• Multi-department coordination and business system integration
|
|
||||||
|
|
||||||
Target users: Business process managers, IT automation specialists, and organizations
|
|
||||||
requiring consistent, repeatable document processing workflows.
|
|
||||||
""")
|
|
||||||
public @interface PipelineApi {}
|
|
||||||
-47
@@ -1,47 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Proprietary UI Data API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/proprietary/ui-data"), and OpenAPI @Tag. Note:
|
|
||||||
* Controllers using this annotation should also add @EnterpriseEndpoint.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/proprietary/ui-data")
|
|
||||||
@Tag(
|
|
||||||
name = "Proprietary UI Data",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Enterprise user interface data services for commercial deployments and advanced business features.
|
|
||||||
|
|
||||||
This endpoint group provides enhanced data services for commercial and enterprise features,
|
|
||||||
supporting advanced business workflows and professional-grade functionality.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Enterprise-grade dashboards, multi-tenant deployment, and business intelligence
|
|
||||||
• Organizational hierarchy management and commercial feature licensing
|
|
||||||
• Professional support integration and advanced workflow automation
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• ERP integration, CRM development, and executive reporting dashboards
|
|
||||||
• Multi-subsidiary management, professional service delivery, and compliance interfaces
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Large-scale deployment management and white-label solution development
|
|
||||||
• Advanced system integration and commercial feature rollout
|
|
||||||
|
|
||||||
Target users: Enterprise administrators, business analysts, and organizations utilizing
|
|
||||||
commercial features and advanced business capabilities.
|
|
||||||
""")
|
|
||||||
public @interface ProprietaryUiDataApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Security API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/security"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/security")
|
|
||||||
@Tag(
|
|
||||||
name = "Security",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Document security and protection services for confidential and sensitive content.
|
|
||||||
|
|
||||||
This endpoint group provides essential security operations for organizations handling
|
|
||||||
sensitive documents and materials requiring controlled access.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Legal confidentiality, healthcare privacy (HIPAA), and financial regulatory compliance
|
|
||||||
• Government classified handling, corporate IP protection, and educational privacy (FERPA)
|
|
||||||
• Contract security for business transactions
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Document authentication, confidential sharing, and secure archiving
|
|
||||||
• Content watermarking, access control, and privacy protection through redaction
|
|
||||||
|
|
||||||
Industry scenarios:
|
|
||||||
• Legal discovery, medical records exchange, financial audit documentation
|
|
||||||
• Enterprise policy enforcement and data governance
|
|
||||||
|
|
||||||
Target users: Legal professionals, healthcare administrators, compliance officers,
|
|
||||||
government agencies, and enterprises handling sensitive content.
|
|
||||||
""")
|
|
||||||
public @interface SecurityApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Settings API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/settings"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/settings")
|
|
||||||
@Tag(
|
|
||||||
name = "Settings",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
User preferences and application customization for personalized workflow optimization.
|
|
||||||
|
|
||||||
This endpoint group provides preference management capabilities for users and
|
|
||||||
organizations to customize their document processing experience.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Workflow optimization, accessibility compliance, and corporate branding
|
|
||||||
• Multi-language support, user personalization, and business system integration
|
|
||||||
• Organizational policy compliance
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Corporate branding, productivity optimization, and accessibility compliance
|
|
||||||
• Change management facilitation and training efficiency improvement
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• User onboarding, department-specific customization, and system migration
|
|
||||||
• Multi-tenant customization and project-based configuration adjustments
|
|
||||||
|
|
||||||
Target users: End users, department managers, and organizations focused on optimizing
|
|
||||||
user experience and workflow efficiency through personalization.
|
|
||||||
""")
|
|
||||||
public @interface SettingsApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for Team Management API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/team"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/team")
|
|
||||||
@Tag(
|
|
||||||
name = "Team",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
Team management and collaboration services for organized document processing workflows.
|
|
||||||
|
|
||||||
This endpoint group enables organizations to structure collaborative document processing
|
|
||||||
activities through team-based organization and resource management.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Department-based processing, project collaboration, and cross-functional coordination
|
|
||||||
• Client-specific team isolation, temporary project teams, and training coordination
|
|
||||||
• Compliance team coordination for regulatory processing
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Matrix organization support, client service delivery, and cost center allocation
|
|
||||||
• Scalable collaboration, knowledge management, and team-based quality assurance
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Large-scale processing coordination and temporary team formation
|
|
||||||
• M&A integration, remote collaboration, and knowledge transfer management
|
|
||||||
|
|
||||||
Target users: Team leaders, project managers, and organizations requiring structured
|
|
||||||
collaborative environments for document processing activities.
|
|
||||||
""")
|
|
||||||
public @interface TeamApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for UI Data API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/ui-data"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/ui-data")
|
|
||||||
@Tag(
|
|
||||||
name = "UI Data",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
User interface data services for dynamic frontend applications and user experience customization.
|
|
||||||
|
|
||||||
This endpoint group provides data services for frontend applications to render personalized
|
|
||||||
interfaces and deliver optimized experiences based on system configuration.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Dynamic UI customization, multi-language support, and feature configuration
|
|
||||||
• Real-time status delivery, corporate branding, and mobile optimization
|
|
||||||
• Progressive web application (PWA) configuration
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Brand customization, user experience optimization, and accessibility compliance
|
|
||||||
• Multi-tenant customization, training support, and performance optimization
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Frontend deployment, UI A/B testing, and system integration
|
|
||||||
• Mobile synchronization and offline capability enhancement
|
|
||||||
|
|
||||||
Target users: Frontend developers, UI/UX designers, and organizations requiring
|
|
||||||
customizable user interfaces and optimized user experiences.
|
|
||||||
""")
|
|
||||||
public @interface UiDataApi {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package stirling.software.common.annotations.api;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combined annotation for User Management API controllers.
|
|
||||||
* Includes @RestController, @RequestMapping("/api/v1/user"), and OpenAPI @Tag.
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/user")
|
|
||||||
@Tag(
|
|
||||||
name = "User",
|
|
||||||
description =
|
|
||||||
"""
|
|
||||||
User management and authentication services for multi-user and enterprise environments.
|
|
||||||
|
|
||||||
This endpoint group provides user lifecycle management capabilities for organizations
|
|
||||||
deploying Stirling PDF in multi-user scenarios.
|
|
||||||
|
|
||||||
Common use cases:
|
|
||||||
• Employee onboarding/offboarding and corporate access control
|
|
||||||
• Department-based permissions, regulatory compliance, and SSO integration
|
|
||||||
• Multi-tenant deployment and guest user access management
|
|
||||||
|
|
||||||
Business applications:
|
|
||||||
• Enterprise IAM integration, security governance, and cost allocation
|
|
||||||
• Compliance reporting, workflow management, and partner collaboration
|
|
||||||
|
|
||||||
Operational scenarios:
|
|
||||||
• Large-scale provisioning, automated HR integration, and emergency access
|
|
||||||
• User migration and self-service profile maintenance
|
|
||||||
|
|
||||||
Target users: IT administrators, HR departments, and organizations requiring
|
|
||||||
structured user management and enterprise identity integration.
|
|
||||||
""")
|
|
||||||
public @interface UserApi {}
|
|
||||||
@@ -4,8 +4,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
import jakarta.validation.constraints.AssertTrue;
|
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -13,20 +11,15 @@ import lombok.NoArgsConstructor;
|
|||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@Schema(description = "PDF file input - either upload a file or provide a server-side file ID")
|
|
||||||
public class PDFFile {
|
public class PDFFile {
|
||||||
@Schema(description = "The input PDF file", format = "binary")
|
@Schema(
|
||||||
|
description = "The input PDF file",
|
||||||
|
contentMediaType = "application/pdf",
|
||||||
|
format = "binary")
|
||||||
private MultipartFile fileInput;
|
private MultipartFile fileInput;
|
||||||
|
|
||||||
@Schema(
|
@Schema(
|
||||||
description =
|
description = "File ID for server-side files (can be used instead of fileInput)",
|
||||||
"File ID for server-side files (can be used instead of fileInput if job was previously done on file in async mode)")
|
example = "a1b2c3d4-5678-90ab-cdef-ghijklmnopqr")
|
||||||
private String fileId;
|
private String fileId;
|
||||||
|
|
||||||
@AssertTrue(message = "Either fileInput or fileId must be provided")
|
|
||||||
@Schema(hidden = true)
|
|
||||||
private boolean isValid() {
|
|
||||||
return (fileInput != null && (fileId == null || fileId.trim().isEmpty()))
|
|
||||||
|| (fileId != null && !fileId.trim().isEmpty() && fileInput == null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
package stirling.software.common.service;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
public interface ServerCertificateServiceInterface {
|
|
||||||
|
|
||||||
boolean isEnabled();
|
|
||||||
|
|
||||||
boolean hasServerCertificate();
|
|
||||||
|
|
||||||
void initializeServerCertificate();
|
|
||||||
|
|
||||||
KeyStore getServerKeyStore() throws Exception;
|
|
||||||
|
|
||||||
String getServerCertificatePassword();
|
|
||||||
|
|
||||||
X509Certificate getServerCertificate() throws Exception;
|
|
||||||
|
|
||||||
byte[] getServerCertificatePublicKey() throws Exception;
|
|
||||||
|
|
||||||
void uploadServerCertificate(InputStream p12Stream, String password) throws Exception;
|
|
||||||
|
|
||||||
void deleteServerCertificate() throws Exception;
|
|
||||||
|
|
||||||
ServerCertificateInfo getServerCertificateInfo() throws Exception;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
class ServerCertificateInfo {
|
|
||||||
private final boolean exists;
|
|
||||||
private final String subject;
|
|
||||||
private final String issuer;
|
|
||||||
private final Date validFrom;
|
|
||||||
private final Date validTo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -237,7 +237,6 @@ public class EndpointConfiguration {
|
|||||||
addEndpointToGroup("PageOps", "pdf-organizer");
|
addEndpointToGroup("PageOps", "pdf-organizer");
|
||||||
addEndpointToGroup("PageOps", "rotate-pdf");
|
addEndpointToGroup("PageOps", "rotate-pdf");
|
||||||
addEndpointToGroup("PageOps", "multi-page-layout");
|
addEndpointToGroup("PageOps", "multi-page-layout");
|
||||||
addEndpointToGroup("PageOps", "booklet-imposition");
|
|
||||||
addEndpointToGroup("PageOps", "scale-pages");
|
addEndpointToGroup("PageOps", "scale-pages");
|
||||||
addEndpointToGroup("PageOps", "crop");
|
addEndpointToGroup("PageOps", "crop");
|
||||||
addEndpointToGroup("PageOps", "extract-page");
|
addEndpointToGroup("PageOps", "extract-page");
|
||||||
@@ -367,7 +366,6 @@ public class EndpointConfiguration {
|
|||||||
addEndpointToGroup("Java", "cert-sign");
|
addEndpointToGroup("Java", "cert-sign");
|
||||||
addEndpointToGroup("Java", "remove-cert-sign");
|
addEndpointToGroup("Java", "remove-cert-sign");
|
||||||
addEndpointToGroup("Java", "multi-page-layout");
|
addEndpointToGroup("Java", "multi-page-layout");
|
||||||
addEndpointToGroup("Java", "booklet-imposition");
|
|
||||||
addEndpointToGroup("Java", "scale-pages");
|
addEndpointToGroup("Java", "scale-pages");
|
||||||
addEndpointToGroup("Java", "add-page-numbers");
|
addEndpointToGroup("Java", "add-page-numbers");
|
||||||
addEndpointToGroup("Java", "auto-rename");
|
addEndpointToGroup("Java", "auto-rename");
|
||||||
|
|||||||
-188
@@ -1,188 +0,0 @@
|
|||||||
package stirling.software.SPDF.config;
|
|
||||||
|
|
||||||
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
|
||||||
import io.swagger.v3.oas.models.Operation;
|
|
||||||
import io.swagger.v3.oas.models.PathItem;
|
|
||||||
import io.swagger.v3.oas.models.media.Content;
|
|
||||||
import io.swagger.v3.oas.models.media.MediaType;
|
|
||||||
import io.swagger.v3.oas.models.media.Schema;
|
|
||||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Global OpenAPI customizer that adds standard error responses (400, 413, 422, 500) to all API
|
|
||||||
* operations under /api/v1/** paths.
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class GlobalErrorResponseCustomizer implements GlobalOpenApiCustomizer {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void customise(OpenAPI openApi) {
|
|
||||||
if (openApi.getPaths() == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
openApi.getPaths()
|
|
||||||
.forEach(
|
|
||||||
(path, pathItem) -> {
|
|
||||||
if (path.startsWith("/api/v1/")) {
|
|
||||||
addErrorResponsesToPathItem(pathItem);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addErrorResponsesToPathItem(PathItem pathItem) {
|
|
||||||
if (pathItem.getPost() != null) {
|
|
||||||
addStandardErrorResponses(pathItem.getPost());
|
|
||||||
}
|
|
||||||
if (pathItem.getPut() != null) {
|
|
||||||
addStandardErrorResponses(pathItem.getPut());
|
|
||||||
}
|
|
||||||
if (pathItem.getPatch() != null) {
|
|
||||||
addStandardErrorResponses(pathItem.getPatch());
|
|
||||||
}
|
|
||||||
if (pathItem.getDelete() != null) {
|
|
||||||
addStandardErrorResponses(pathItem.getDelete());
|
|
||||||
}
|
|
||||||
if (pathItem.getGet() != null) {
|
|
||||||
addStandardErrorResponses(pathItem.getGet());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addStandardErrorResponses(Operation operation) {
|
|
||||||
if (operation.getResponses() == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only add error responses if they don't already exist
|
|
||||||
if (!operation.getResponses().containsKey("400")) {
|
|
||||||
operation.getResponses().addApiResponse("400", create400Response());
|
|
||||||
}
|
|
||||||
if (!operation.getResponses().containsKey("413")) {
|
|
||||||
operation.getResponses().addApiResponse("413", create413Response());
|
|
||||||
}
|
|
||||||
if (!operation.getResponses().containsKey("422")) {
|
|
||||||
operation.getResponses().addApiResponse("422", create422Response());
|
|
||||||
}
|
|
||||||
if (!operation.getResponses().containsKey("500")) {
|
|
||||||
operation.getResponses().addApiResponse("500", create500Response());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApiResponse create400Response() {
|
|
||||||
return new ApiResponse()
|
|
||||||
.description(
|
|
||||||
"Bad request - Invalid input parameters, unsupported format, or corrupted file")
|
|
||||||
.content(
|
|
||||||
new Content()
|
|
||||||
.addMediaType(
|
|
||||||
"application/json",
|
|
||||||
new MediaType()
|
|
||||||
.schema(
|
|
||||||
createErrorSchema(
|
|
||||||
400,
|
|
||||||
"Invalid input parameters or corrupted file",
|
|
||||||
"/api/v1/example/endpoint"))
|
|
||||||
.example(
|
|
||||||
createErrorExample(
|
|
||||||
400,
|
|
||||||
"Invalid input parameters or corrupted file",
|
|
||||||
"/api/v1/example/endpoint"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApiResponse create413Response() {
|
|
||||||
return new ApiResponse()
|
|
||||||
.description("Payload too large - File exceeds maximum allowed size")
|
|
||||||
.content(
|
|
||||||
new Content()
|
|
||||||
.addMediaType(
|
|
||||||
"application/json",
|
|
||||||
new MediaType()
|
|
||||||
.schema(
|
|
||||||
createErrorSchema(
|
|
||||||
413,
|
|
||||||
"File size exceeds maximum allowed limit",
|
|
||||||
"/api/v1/example/endpoint"))
|
|
||||||
.example(
|
|
||||||
createErrorExample(
|
|
||||||
413,
|
|
||||||
"File size exceeds maximum allowed limit",
|
|
||||||
"/api/v1/example/endpoint"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApiResponse create422Response() {
|
|
||||||
return new ApiResponse()
|
|
||||||
.description("Unprocessable entity - File is valid but cannot be processed")
|
|
||||||
.content(
|
|
||||||
new Content()
|
|
||||||
.addMediaType(
|
|
||||||
"application/json",
|
|
||||||
new MediaType()
|
|
||||||
.schema(
|
|
||||||
createErrorSchema(
|
|
||||||
422,
|
|
||||||
"File is valid but cannot be processed",
|
|
||||||
"/api/v1/example/endpoint"))
|
|
||||||
.example(
|
|
||||||
createErrorExample(
|
|
||||||
422,
|
|
||||||
"File is valid but cannot be processed",
|
|
||||||
"/api/v1/example/endpoint"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApiResponse create500Response() {
|
|
||||||
return new ApiResponse()
|
|
||||||
.description("Internal server error - Unexpected error during processing")
|
|
||||||
.content(
|
|
||||||
new Content()
|
|
||||||
.addMediaType(
|
|
||||||
"application/json",
|
|
||||||
new MediaType()
|
|
||||||
.schema(
|
|
||||||
createErrorSchema(
|
|
||||||
500,
|
|
||||||
"Unexpected error during processing",
|
|
||||||
"/api/v1/example/endpoint"))
|
|
||||||
.example(
|
|
||||||
createErrorExample(
|
|
||||||
500,
|
|
||||||
"Unexpected error during processing",
|
|
||||||
"/api/v1/example/endpoint"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Schema<?> createErrorSchema(int status, String message, String path) {
|
|
||||||
return new Schema<>()
|
|
||||||
.type("object")
|
|
||||||
.addProperty("status", new Schema<>().type("integer").example(status))
|
|
||||||
.addProperty("error", new Schema<>().type("string").example(getErrorType(status)))
|
|
||||||
.addProperty("message", new Schema<>().type("string").example(message))
|
|
||||||
.addProperty(
|
|
||||||
"timestamp",
|
|
||||||
new Schema<>()
|
|
||||||
.type("string")
|
|
||||||
.format("date-time")
|
|
||||||
.example("2024-01-15T10:30:00Z"))
|
|
||||||
.addProperty("path", new Schema<>().type("string").example(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object createErrorExample(int status, String message, String path) {
|
|
||||||
return java.util.Map.of(
|
|
||||||
"status", status,
|
|
||||||
"error", getErrorType(status),
|
|
||||||
"message", message,
|
|
||||||
"timestamp", "2024-01-15T10:30:00Z",
|
|
||||||
"path", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getErrorType(int status) {
|
|
||||||
return switch (status) {
|
|
||||||
case 400 -> "Bad Request";
|
|
||||||
case 413 -> "Payload Too Large";
|
|
||||||
case 422 -> "Unprocessable Entity";
|
|
||||||
case 500 -> "Internal Server Error";
|
|
||||||
default -> "Error";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
package stirling.software.SPDF.config;
|
package stirling.software.SPDF.config;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springdoc.core.customizers.OpenApiCustomizer;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@@ -11,10 +8,6 @@ import io.swagger.v3.oas.models.OpenAPI;
|
|||||||
import io.swagger.v3.oas.models.info.Contact;
|
import io.swagger.v3.oas.models.info.Contact;
|
||||||
import io.swagger.v3.oas.models.info.Info;
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
import io.swagger.v3.oas.models.info.License;
|
import io.swagger.v3.oas.models.info.License;
|
||||||
import io.swagger.v3.oas.models.media.ComposedSchema;
|
|
||||||
import io.swagger.v3.oas.models.media.ObjectSchema;
|
|
||||||
import io.swagger.v3.oas.models.media.Schema;
|
|
||||||
import io.swagger.v3.oas.models.media.StringSchema;
|
|
||||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||||
import io.swagger.v3.oas.models.servers.Server;
|
import io.swagger.v3.oas.models.servers.Server;
|
||||||
@@ -49,7 +42,8 @@ public class OpenApiConfig {
|
|||||||
new License()
|
new License()
|
||||||
.name("MIT")
|
.name("MIT")
|
||||||
.url(
|
.url(
|
||||||
"https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/LICENSE"))
|
"https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/LICENSE")
|
||||||
|
.identifier("MIT"))
|
||||||
.termsOfService("https://www.stirlingpdf.com/terms")
|
.termsOfService("https://www.stirlingpdf.com/terms")
|
||||||
.contact(
|
.contact(
|
||||||
new Contact()
|
new Contact()
|
||||||
@@ -58,7 +52,7 @@ public class OpenApiConfig {
|
|||||||
.email("contact@stirlingpdf.com"))
|
.email("contact@stirlingpdf.com"))
|
||||||
.description(DEFAULT_DESCRIPTION);
|
.description(DEFAULT_DESCRIPTION);
|
||||||
|
|
||||||
OpenAPI openAPI = new OpenAPI().info(info).openapi("3.0.3");
|
OpenAPI openAPI = new OpenAPI().info(info);
|
||||||
|
|
||||||
// Add server configuration from environment variable
|
// Add server configuration from environment variable
|
||||||
String swaggerServerUrl = System.getenv("SWAGGER_SERVER_URL");
|
String swaggerServerUrl = System.getenv("SWAGGER_SERVER_URL");
|
||||||
@@ -67,83 +61,16 @@ public class OpenApiConfig {
|
|||||||
openAPI.addServersItem(server);
|
openAPI.addServersItem(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add ErrorResponse schema to components
|
|
||||||
Schema<?> errorResponseSchema =
|
|
||||||
new Schema<>()
|
|
||||||
.type("object")
|
|
||||||
.addProperty(
|
|
||||||
"timestamp",
|
|
||||||
new Schema<>()
|
|
||||||
.type("string")
|
|
||||||
.format("date-time")
|
|
||||||
.description("Error timestamp"))
|
|
||||||
.addProperty(
|
|
||||||
"status",
|
|
||||||
new Schema<>().type("integer").description("HTTP status code"))
|
|
||||||
.addProperty(
|
|
||||||
"error", new Schema<>().type("string").description("Error type"))
|
|
||||||
.addProperty(
|
|
||||||
"message",
|
|
||||||
new Schema<>().type("string").description("Error message"))
|
|
||||||
.addProperty(
|
|
||||||
"path", new Schema<>().type("string").description("Request path"))
|
|
||||||
.description("Standard error response format");
|
|
||||||
|
|
||||||
Components components = new Components().addSchemas("ErrorResponse", errorResponseSchema);
|
|
||||||
|
|
||||||
if (!applicationProperties.getSecurity().getEnableLogin()) {
|
if (!applicationProperties.getSecurity().getEnableLogin()) {
|
||||||
return openAPI.components(components);
|
return openAPI.components(new Components());
|
||||||
} else {
|
} else {
|
||||||
SecurityScheme apiKeyScheme =
|
SecurityScheme apiKeyScheme =
|
||||||
new SecurityScheme()
|
new SecurityScheme()
|
||||||
.type(SecurityScheme.Type.APIKEY)
|
.type(SecurityScheme.Type.APIKEY)
|
||||||
.in(SecurityScheme.In.HEADER)
|
.in(SecurityScheme.In.HEADER)
|
||||||
.name("X-API-KEY");
|
.name("X-API-KEY");
|
||||||
components.addSecuritySchemes("apiKey", apiKeyScheme);
|
return openAPI.components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
|
||||||
return openAPI.components(components)
|
|
||||||
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
|
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
OpenApiCustomizer pdfFileOneOfCustomizer() {
|
|
||||||
return openApi -> {
|
|
||||||
var components = openApi.getComponents();
|
|
||||||
var schemas = components.getSchemas();
|
|
||||||
|
|
||||||
// Define the two shapes
|
|
||||||
var upload =
|
|
||||||
new ObjectSchema()
|
|
||||||
.name("PDFFileUpload")
|
|
||||||
.description("Upload a PDF file")
|
|
||||||
.addProperty("fileInput", new StringSchema().format("binary"))
|
|
||||||
.addRequiredItem("fileInput");
|
|
||||||
|
|
||||||
var ref =
|
|
||||||
new ObjectSchema()
|
|
||||||
.name("PDFFileRef")
|
|
||||||
.description("Reference a server-side file")
|
|
||||||
.addProperty(
|
|
||||||
"fileId",
|
|
||||||
new StringSchema()
|
|
||||||
.example("a1b2c3d4-5678-90ab-cdef-ghijklmnopqr"))
|
|
||||||
.addRequiredItem("fileId");
|
|
||||||
|
|
||||||
schemas.put("PDFFileUpload", upload);
|
|
||||||
schemas.put("PDFFileRef", ref);
|
|
||||||
|
|
||||||
// Create the oneOf schema
|
|
||||||
var pdfFileOneOf =
|
|
||||||
new ComposedSchema()
|
|
||||||
.oneOf(
|
|
||||||
List.of(
|
|
||||||
new Schema<>()
|
|
||||||
.$ref("#/components/schemas/PDFFileUpload"),
|
|
||||||
new Schema<>().$ref("#/components/schemas/PDFFileRef")))
|
|
||||||
.description("Either upload a file or provide a server-side file ID");
|
|
||||||
|
|
||||||
// Replace PDFFile schema
|
|
||||||
schemas.put("PDFFile", pdfFileOneOf);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
package stirling.software.SPDF.config;
|
|
||||||
|
|
||||||
import org.springdoc.core.customizers.OpenApiCustomizer;
|
|
||||||
import org.springdoc.core.models.GroupedOpenApi;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class SpringDocConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public GroupedOpenApi pdfProcessingApi(
|
|
||||||
@Qualifier("pdfFileOneOfCustomizer") OpenApiCustomizer pdfFileOneOfCustomizer) {
|
|
||||||
return GroupedOpenApi.builder()
|
|
||||||
.group("file-processing")
|
|
||||||
.displayName("File Processing")
|
|
||||||
.pathsToMatch("/api/v1/**")
|
|
||||||
.pathsToExclude(
|
|
||||||
"/api/v1/admin/**",
|
|
||||||
"/api/v1/user/**",
|
|
||||||
"/api/v1/settings/**",
|
|
||||||
"/api/v1/team/**",
|
|
||||||
"/api/v1/ui-data/**",
|
|
||||||
"/api/v1/proprietary/ui-data/**",
|
|
||||||
"/api/v1/info/**",
|
|
||||||
"/api/v1/general/job/**",
|
|
||||||
"/api/v1/general/files/**")
|
|
||||||
.addOpenApiCustomizer(pdfFileOneOfCustomizer)
|
|
||||||
.addOpenApiCustomizer(
|
|
||||||
openApi -> {
|
|
||||||
openApi.info(
|
|
||||||
openApi.getInfo()
|
|
||||||
.title("Stirling PDF - Processing API")
|
|
||||||
.description(
|
|
||||||
"API documentation for PDF processing operations including conversion, manipulation, security, and utilities."));
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public GroupedOpenApi adminApi() {
|
|
||||||
return GroupedOpenApi.builder()
|
|
||||||
.group("management")
|
|
||||||
.displayName("Management")
|
|
||||||
.pathsToMatch(
|
|
||||||
"/api/v1/admin/**",
|
|
||||||
"/api/v1/user/**",
|
|
||||||
"/api/v1/settings/**",
|
|
||||||
"/api/v1/team/**")
|
|
||||||
.addOpenApiCustomizer(
|
|
||||||
openApi -> {
|
|
||||||
openApi.info(
|
|
||||||
openApi.getInfo()
|
|
||||||
.title("Stirling PDF - Admin API")
|
|
||||||
.description(
|
|
||||||
"API documentation for administrative functions, user management, and system configuration."));
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public GroupedOpenApi systemApi() {
|
|
||||||
return GroupedOpenApi.builder()
|
|
||||||
.group("system")
|
|
||||||
.displayName("System & UI API")
|
|
||||||
.pathsToMatch(
|
|
||||||
"/api/v1/ui-data/**",
|
|
||||||
"/api/v1/proprietary/ui-data/**",
|
|
||||||
"/api/v1/info/**",
|
|
||||||
"/api/v1/general/job/**",
|
|
||||||
"/api/v1/general/files/**")
|
|
||||||
.addOpenApiCustomizer(
|
|
||||||
openApi -> {
|
|
||||||
openApi.info(
|
|
||||||
openApi.getInfo()
|
|
||||||
.title("Stirling PDF - System API")
|
|
||||||
.description(
|
|
||||||
"API documentation for system information, UI data, and utility endpoints."));
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for PDF to CSV conversions. Use for endpoints that convert PDF tables to
|
|
||||||
* CSV format.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "PDF tables extracted successfully to CSV format",
|
|
||||||
content = {
|
|
||||||
@Content(
|
|
||||||
mediaType = "text/csv",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description =
|
|
||||||
"CSV file containing extracted table data")),
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/zip",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description =
|
|
||||||
"ZIP archive containing multiple CSV files when multiple tables are extracted"))
|
|
||||||
}),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "400",
|
|
||||||
description = "Invalid PDF file or no tables found for extraction",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(responseCode = "204", description = "No tables found in the PDF"),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "500",
|
|
||||||
description = "Internal server error during table extraction",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class)))
|
|
||||||
})
|
|
||||||
public @interface CsvConversionResponse {}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
@Schema(description = "Standard error response")
|
|
||||||
public class ErrorResponse {
|
|
||||||
|
|
||||||
@Schema(description = "HTTP status code", example = "400")
|
|
||||||
private int status;
|
|
||||||
|
|
||||||
@Schema(
|
|
||||||
description = "Error message describing what went wrong",
|
|
||||||
example = "Invalid PDF file or corrupted data")
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
@Schema(description = "Timestamp when the error occurred", example = "2024-01-15T10:30:00Z")
|
|
||||||
private String timestamp;
|
|
||||||
|
|
||||||
@Schema(
|
|
||||||
description = "Request path where the error occurred",
|
|
||||||
example = "/api/v1/{endpoint-path}")
|
|
||||||
private String path;
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for filter operations that conditionally return the original file. Use
|
|
||||||
* for operations like text filters, page count filters, size filters, etc. Returns the original PDF
|
|
||||||
* if condition is met, otherwise returns no content (204).
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "Filter condition met - returns the original PDF file",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/pdf",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description = "The original PDF file"))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "204",
|
|
||||||
description = "Filter condition not met - no content returned",
|
|
||||||
content = @Content()),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "400",
|
|
||||||
description = "Bad request - Invalid filter parameters or corrupted PDF",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "413",
|
|
||||||
description = "Payload too large - File exceeds maximum allowed size",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "422",
|
|
||||||
description =
|
|
||||||
"Unprocessable entity - PDF is valid but cannot be analyzed for filtering",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "500",
|
|
||||||
description = "Internal server error - Unexpected error during PDF analysis",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class)))
|
|
||||||
})
|
|
||||||
public @interface FilterResponse {}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for PDF to HTML conversions. Use for endpoints that convert PDF to HTML
|
|
||||||
* format.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "PDF converted successfully to HTML format",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "text/html",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description = "HTML file converted from PDF")))
|
|
||||||
})
|
|
||||||
public @interface HtmlConversionResponse {}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for JavaScript extraction from PDFs. Use for endpoints that extract
|
|
||||||
* JavaScript code from PDF documents.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "JavaScript extracted successfully from PDF",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "text/plain",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description =
|
|
||||||
"JavaScript code extracted from PDF")))
|
|
||||||
})
|
|
||||||
public @interface JavaScriptResponse {}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for operations that return JSON data or analysis results. Use for
|
|
||||||
* analysis operations, metadata extraction, info operations, etc.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "Analysis or data extraction completed successfully",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "object",
|
|
||||||
description =
|
|
||||||
"JSON object containing the requested data or analysis results"))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "400",
|
|
||||||
description = "Invalid PDF file or request parameters",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "500",
|
|
||||||
description = "Internal server error during processing",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class)))
|
|
||||||
})
|
|
||||||
public @interface JsonDataResponse {}
|
|
||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for PDF to Markdown conversions. Use for endpoints that convert PDF to
|
|
||||||
* Markdown format.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "PDF converted successfully to Markdown format",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "text/markdown",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description =
|
|
||||||
"Markdown file converted from PDF")))
|
|
||||||
})
|
|
||||||
public @interface MarkdownConversionResponse {}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for operations that may return multiple files or a ZIP archive. Use for
|
|
||||||
* operations like PDF to images, split PDF, or multiple file conversions.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description =
|
|
||||||
"Files processed successfully. Returns single file or ZIP archive containing multiple files.",
|
|
||||||
content = {
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/pdf",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description = "Single PDF file result")),
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/zip",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description =
|
|
||||||
"ZIP archive containing multiple output files")),
|
|
||||||
@Content(
|
|
||||||
mediaType = "image/png",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description = "Single image file (PNG)")),
|
|
||||||
@Content(
|
|
||||||
mediaType = "image/jpeg",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description = "Single image file (JPEG)"))
|
|
||||||
}),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "400",
|
|
||||||
description = "Invalid PDF file or request parameters",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "500",
|
|
||||||
description = "Internal server error during processing",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class)))
|
|
||||||
})
|
|
||||||
public @interface MultiFileResponse {}
|
|
||||||
-66
@@ -1,66 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for PDF to PowerPoint presentation conversions. Use for endpoints that
|
|
||||||
* convert PDF to PPTX format.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "PDF converted successfully to PowerPoint presentation",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType =
|
|
||||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description =
|
|
||||||
"Microsoft PowerPoint presentation (PPTX)"))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "400",
|
|
||||||
description =
|
|
||||||
"Bad request - Invalid input parameters, unsupported format, or corrupted PDF",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "413",
|
|
||||||
description = "Payload too large - File exceeds maximum allowed size",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "422",
|
|
||||||
description =
|
|
||||||
"Unprocessable entity - PDF is valid but cannot be converted to PowerPoint format",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "500",
|
|
||||||
description =
|
|
||||||
"Internal server error - Unexpected error during PowerPoint conversion",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class)))
|
|
||||||
})
|
|
||||||
public @interface PowerPointConversionResponse {}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Standard API response annotation for PDF operations that take PDF input and return PDF output.
|
|
||||||
* Use for single PDF input → single PDF output (SISO) operations like rotate, compress, etc.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "PDF processed successfully",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/pdf",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description = "The processed PDF file"))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "400",
|
|
||||||
description = "Invalid PDF file or request parameters",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "500",
|
|
||||||
description = "Internal server error during processing",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class)))
|
|
||||||
})
|
|
||||||
public @interface StandardPdfResponse {}
|
|
||||||
-69
@@ -1,69 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for PDF to plain text conversions. Use for endpoints that extract text
|
|
||||||
* content from PDF.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "PDF text extracted successfully",
|
|
||||||
content = {
|
|
||||||
@Content(
|
|
||||||
mediaType = "text/plain",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
description =
|
|
||||||
"Plain text content extracted from PDF")),
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/rtf",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description = "Rich Text Format document"))
|
|
||||||
}),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "400",
|
|
||||||
description = "Bad request - Invalid input parameters or corrupted PDF",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "413",
|
|
||||||
description = "Payload too large - File exceeds maximum allowed size",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "422",
|
|
||||||
description = "Unprocessable entity - PDF is valid but text extraction failed",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "500",
|
|
||||||
description = "Internal server error - Unexpected error during text extraction",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class)))
|
|
||||||
})
|
|
||||||
public @interface TextPlainConversionResponse {}
|
|
||||||
-72
@@ -1,72 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for PDF to Word document conversions. Use for endpoints that convert PDF
|
|
||||||
* to DOCX/DOC formats.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "PDF converted successfully to Word document",
|
|
||||||
content = {
|
|
||||||
@Content(
|
|
||||||
mediaType =
|
|
||||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description = "Microsoft Word document (DOCX)")),
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/msword",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description = "Microsoft Word document (DOC)"))
|
|
||||||
}),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "400",
|
|
||||||
description =
|
|
||||||
"Bad request - Invalid input parameters, unsupported format, or corrupted PDF",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "413",
|
|
||||||
description = "Payload too large - File exceeds maximum allowed size",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "422",
|
|
||||||
description =
|
|
||||||
"Unprocessable entity - PDF is valid but cannot be converted to Word format",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class))),
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "500",
|
|
||||||
description = "Internal server error - Unexpected error during Word conversion",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/json",
|
|
||||||
schema = @Schema(implementation = ErrorResponse.class)))
|
|
||||||
})
|
|
||||||
public @interface WordConversionResponse {}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
package stirling.software.SPDF.config.swagger;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API response annotation for PDF to XML conversions. Use for endpoints that convert PDF to XML
|
|
||||||
* format.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@ApiResponses(
|
|
||||||
value = {
|
|
||||||
@ApiResponse(
|
|
||||||
responseCode = "200",
|
|
||||||
description = "PDF converted successfully to XML format",
|
|
||||||
content =
|
|
||||||
@Content(
|
|
||||||
mediaType = "application/xml",
|
|
||||||
schema =
|
|
||||||
@Schema(
|
|
||||||
type = "string",
|
|
||||||
format = "binary",
|
|
||||||
description = "XML file converted from PDF")))
|
|
||||||
})
|
|
||||||
public @interface XmlConversionResponse {}
|
|
||||||
+4
-11
@@ -14,23 +14,23 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.JsonDataResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.AnalysisApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
|
|
||||||
@AnalysisApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/analysis")
|
||||||
|
@Tag(name = "Analysis", description = "Analysis APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AnalysisController {
|
public class AnalysisController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/page-count", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/page-count", consumes = "multipart/form-data")
|
||||||
@JsonDataResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Get PDF page count",
|
summary = "Get PDF page count",
|
||||||
description = "Returns total number of pages in PDF. Input:PDF Output:JSON Type:SISO")
|
description = "Returns total number of pages in PDF. Input:PDF Output:JSON Type:SISO")
|
||||||
@@ -41,7 +41,6 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/basic-info", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/basic-info", consumes = "multipart/form-data")
|
||||||
@JsonDataResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Get basic PDF information",
|
summary = "Get basic PDF information",
|
||||||
description = "Returns page count, version, file size. Input:PDF Output:JSON Type:SISO")
|
description = "Returns page count, version, file size. Input:PDF Output:JSON Type:SISO")
|
||||||
@@ -56,7 +55,6 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/document-properties", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/document-properties", consumes = "multipart/form-data")
|
||||||
@JsonDataResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Get PDF document properties",
|
summary = "Get PDF document properties",
|
||||||
description = "Returns title, author, subject, etc. Input:PDF Output:JSON Type:SISO")
|
description = "Returns title, author, subject, etc. Input:PDF Output:JSON Type:SISO")
|
||||||
@@ -80,7 +78,6 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/page-dimensions", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/page-dimensions", consumes = "multipart/form-data")
|
||||||
@JsonDataResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Get page dimensions for all pages",
|
summary = "Get page dimensions for all pages",
|
||||||
description = "Returns width and height of each page. Input:PDF Output:JSON Type:SISO")
|
description = "Returns width and height of each page. Input:PDF Output:JSON Type:SISO")
|
||||||
@@ -101,7 +98,6 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/form-fields", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/form-fields", consumes = "multipart/form-data")
|
||||||
@JsonDataResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Get form field information",
|
summary = "Get form field information",
|
||||||
description =
|
description =
|
||||||
@@ -125,7 +121,6 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/annotation-info", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/annotation-info", consumes = "multipart/form-data")
|
||||||
@JsonDataResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Get annotation information",
|
summary = "Get annotation information",
|
||||||
description = "Returns count and types of annotations. Input:PDF Output:JSON Type:SISO")
|
description = "Returns count and types of annotations. Input:PDF Output:JSON Type:SISO")
|
||||||
@@ -150,7 +145,6 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/font-info", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/font-info", consumes = "multipart/form-data")
|
||||||
@JsonDataResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Get font information",
|
summary = "Get font information",
|
||||||
description =
|
description =
|
||||||
@@ -173,7 +167,6 @@ public class AnalysisController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/security-info", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/security-info", consumes = "multipart/form-data")
|
||||||
@JsonDataResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Get security information",
|
summary = "Get security information",
|
||||||
description =
|
description =
|
||||||
|
|||||||
-324
@@ -1,324 +0,0 @@
|
|||||||
package stirling.software.SPDF.controller.api;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.pdfbox.multipdf.LayerUtility;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
|
||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|
||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|
||||||
import org.apache.pdfbox.util.Matrix;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.BookletImpositionRequest;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v1/general")
|
|
||||||
@Tag(name = "General", description = "General APIs")
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class BookletImpositionController {
|
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/booklet-imposition", consumes = "multipart/form-data")
|
|
||||||
@Operation(
|
|
||||||
summary = "Create a booklet with proper page imposition",
|
|
||||||
description =
|
|
||||||
"This operation combines page reordering for booklet printing with multi-page layout. "
|
|
||||||
+ "It rearranges pages in the correct order for booklet printing and places multiple pages "
|
|
||||||
+ "on each sheet for proper folding and binding. Input:PDF Output:PDF Type:SISO")
|
|
||||||
public ResponseEntity<byte[]> createBookletImposition(
|
|
||||||
@ModelAttribute BookletImpositionRequest request) throws IOException {
|
|
||||||
|
|
||||||
MultipartFile file = request.getFileInput();
|
|
||||||
int pagesPerSheet = request.getPagesPerSheet();
|
|
||||||
boolean addBorder = Boolean.TRUE.equals(request.getAddBorder());
|
|
||||||
String spineLocation =
|
|
||||||
request.getSpineLocation() != null ? request.getSpineLocation() : "LEFT";
|
|
||||||
boolean addGutter = Boolean.TRUE.equals(request.getAddGutter());
|
|
||||||
float gutterSize = request.getGutterSize();
|
|
||||||
boolean doubleSided = Boolean.TRUE.equals(request.getDoubleSided());
|
|
||||||
String duplexPass = request.getDuplexPass() != null ? request.getDuplexPass() : "BOTH";
|
|
||||||
boolean flipOnShortEdge = Boolean.TRUE.equals(request.getFlipOnShortEdge());
|
|
||||||
|
|
||||||
// Validate pages per sheet for booklet - only 2-up landscape is proper booklet
|
|
||||||
if (pagesPerSheet != 2) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Booklet printing uses 2 pages per side (landscape). For 4-up, use the N-up feature.");
|
|
||||||
}
|
|
||||||
|
|
||||||
PDDocument sourceDocument = pdfDocumentFactory.load(file);
|
|
||||||
int totalPages = sourceDocument.getNumberOfPages();
|
|
||||||
|
|
||||||
// Create proper booklet with signature-based page ordering
|
|
||||||
PDDocument newDocument =
|
|
||||||
createSaddleBooklet(
|
|
||||||
sourceDocument,
|
|
||||||
totalPages,
|
|
||||||
addBorder,
|
|
||||||
spineLocation,
|
|
||||||
addGutter,
|
|
||||||
gutterSize,
|
|
||||||
doubleSided,
|
|
||||||
duplexPass,
|
|
||||||
flipOnShortEdge);
|
|
||||||
|
|
||||||
sourceDocument.close();
|
|
||||||
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
newDocument.save(baos);
|
|
||||||
newDocument.close();
|
|
||||||
|
|
||||||
byte[] result = baos.toByteArray();
|
|
||||||
return WebResponseUtils.bytesToWebResponse(
|
|
||||||
result,
|
|
||||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
|
||||||
+ "_booklet.pdf");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int padToMultipleOf4(int n) {
|
|
||||||
return (n + 3) / 4 * 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Side {
|
|
||||||
final int left, right;
|
|
||||||
final boolean isBack;
|
|
||||||
|
|
||||||
Side(int left, int right, boolean isBack) {
|
|
||||||
this.left = left;
|
|
||||||
this.right = right;
|
|
||||||
this.isBack = isBack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Side> saddleStitchSides(
|
|
||||||
int totalPagesOriginal,
|
|
||||||
boolean doubleSided,
|
|
||||||
String duplexPass,
|
|
||||||
boolean flipOnShortEdge) {
|
|
||||||
int N = padToMultipleOf4(totalPagesOriginal);
|
|
||||||
List<Side> out = new ArrayList<>();
|
|
||||||
int sheets = N / 4;
|
|
||||||
|
|
||||||
for (int s = 0; s < sheets; s++) {
|
|
||||||
int a = N - 1 - (s * 2); // left, front
|
|
||||||
int b = (s * 2); // right, front
|
|
||||||
int c = (s * 2) + 1; // left, back
|
|
||||||
int d = N - 2 - (s * 2); // right, back
|
|
||||||
|
|
||||||
// clamp to -1 (blank) if >= totalPagesOriginal
|
|
||||||
a = (a < totalPagesOriginal) ? a : -1;
|
|
||||||
b = (b < totalPagesOriginal) ? b : -1;
|
|
||||||
c = (c < totalPagesOriginal) ? c : -1;
|
|
||||||
d = (d < totalPagesOriginal) ? d : -1;
|
|
||||||
|
|
||||||
// Handle duplex pass selection
|
|
||||||
boolean includeFront = "BOTH".equals(duplexPass) || "FIRST".equals(duplexPass);
|
|
||||||
boolean includeBack = "BOTH".equals(duplexPass) || "SECOND".equals(duplexPass);
|
|
||||||
|
|
||||||
if (includeFront) {
|
|
||||||
out.add(new Side(a, b, false)); // front side
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includeBack) {
|
|
||||||
// For short-edge duplex, swap back-side left/right
|
|
||||||
// Note: flipOnShortEdge is ignored in manual duplex mode since users physically
|
|
||||||
// flip the stack
|
|
||||||
if (doubleSided && flipOnShortEdge) {
|
|
||||||
out.add(new Side(d, c, true)); // swapped back side (automatic duplex only)
|
|
||||||
} else {
|
|
||||||
out.add(new Side(c, d, true)); // normal back side
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PDDocument createSaddleBooklet(
|
|
||||||
PDDocument src,
|
|
||||||
int totalPages,
|
|
||||||
boolean addBorder,
|
|
||||||
String spineLocation,
|
|
||||||
boolean addGutter,
|
|
||||||
float gutterSize,
|
|
||||||
boolean doubleSided,
|
|
||||||
String duplexPass,
|
|
||||||
boolean flipOnShortEdge)
|
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
PDDocument dst = pdfDocumentFactory.createNewDocumentBasedOnOldDocument(src);
|
|
||||||
|
|
||||||
// Derive paper size from source document's first page CropBox
|
|
||||||
PDRectangle srcBox = src.getPage(0).getCropBox();
|
|
||||||
PDRectangle portraitPaper = new PDRectangle(srcBox.getWidth(), srcBox.getHeight());
|
|
||||||
// Force landscape for booklet (Acrobat booklet uses landscape paper to fold to portrait)
|
|
||||||
PDRectangle pageSize = new PDRectangle(portraitPaper.getHeight(), portraitPaper.getWidth());
|
|
||||||
|
|
||||||
// Validate and clamp gutter size
|
|
||||||
if (gutterSize < 0) gutterSize = 0;
|
|
||||||
if (gutterSize >= pageSize.getWidth() / 2f) gutterSize = pageSize.getWidth() / 2f - 1f;
|
|
||||||
|
|
||||||
List<Side> sides = saddleStitchSides(totalPages, doubleSided, duplexPass, flipOnShortEdge);
|
|
||||||
|
|
||||||
for (Side side : sides) {
|
|
||||||
PDPage out = new PDPage(pageSize);
|
|
||||||
dst.addPage(out);
|
|
||||||
|
|
||||||
float cellW = pageSize.getWidth() / 2f;
|
|
||||||
float cellH = pageSize.getHeight();
|
|
||||||
|
|
||||||
// For RIGHT spine (RTL), swap left/right placements
|
|
||||||
boolean rtl = "RIGHT".equalsIgnoreCase(spineLocation);
|
|
||||||
int leftCol = rtl ? 1 : 0;
|
|
||||||
int rightCol = rtl ? 0 : 1;
|
|
||||||
|
|
||||||
// Apply gutter margins with centered gap option
|
|
||||||
float g = addGutter ? gutterSize : 0f;
|
|
||||||
float leftCellX = leftCol * cellW + (g / 2f);
|
|
||||||
float rightCellX = rightCol * cellW - (g / 2f);
|
|
||||||
float leftCellW = cellW - (g / 2f);
|
|
||||||
float rightCellW = cellW - (g / 2f);
|
|
||||||
|
|
||||||
// Create LayerUtility once per page for efficiency
|
|
||||||
LayerUtility layerUtility = new LayerUtility(dst);
|
|
||||||
|
|
||||||
try (PDPageContentStream cs =
|
|
||||||
new PDPageContentStream(
|
|
||||||
dst, out, PDPageContentStream.AppendMode.APPEND, true, true)) {
|
|
||||||
|
|
||||||
if (addBorder) {
|
|
||||||
cs.setLineWidth(1.5f);
|
|
||||||
cs.setStrokingColor(Color.BLACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw left cell
|
|
||||||
drawCell(
|
|
||||||
src,
|
|
||||||
dst,
|
|
||||||
cs,
|
|
||||||
layerUtility,
|
|
||||||
side.left,
|
|
||||||
leftCellX,
|
|
||||||
0f,
|
|
||||||
leftCellW,
|
|
||||||
cellH,
|
|
||||||
addBorder);
|
|
||||||
// draw right cell
|
|
||||||
drawCell(
|
|
||||||
src,
|
|
||||||
dst,
|
|
||||||
cs,
|
|
||||||
layerUtility,
|
|
||||||
side.right,
|
|
||||||
rightCellX,
|
|
||||||
0f,
|
|
||||||
rightCellW,
|
|
||||||
cellH,
|
|
||||||
addBorder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawCell(
|
|
||||||
PDDocument src,
|
|
||||||
PDDocument dst,
|
|
||||||
PDPageContentStream cs,
|
|
||||||
LayerUtility layerUtility,
|
|
||||||
int pageIndex,
|
|
||||||
float cellX,
|
|
||||||
float cellY,
|
|
||||||
float cellW,
|
|
||||||
float cellH,
|
|
||||||
boolean addBorder)
|
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
if (pageIndex < 0) {
|
|
||||||
// Draw border for blank cell if needed
|
|
||||||
if (addBorder) {
|
|
||||||
cs.addRect(cellX, cellY, cellW, cellH);
|
|
||||||
cs.stroke();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PDPage srcPage = src.getPage(pageIndex);
|
|
||||||
PDRectangle r = srcPage.getCropBox(); // Use CropBox instead of MediaBox
|
|
||||||
int rot = (srcPage.getRotation() + 360) % 360;
|
|
||||||
|
|
||||||
// Calculate scale factors, accounting for rotation
|
|
||||||
float sx = cellW / r.getWidth();
|
|
||||||
float sy = cellH / r.getHeight();
|
|
||||||
float s = Math.min(sx, sy);
|
|
||||||
|
|
||||||
// If rotated 90/270 degrees, swap dimensions for fitting
|
|
||||||
if (rot == 90 || rot == 270) {
|
|
||||||
sx = cellW / r.getHeight();
|
|
||||||
sy = cellH / r.getWidth();
|
|
||||||
s = Math.min(sx, sy);
|
|
||||||
}
|
|
||||||
|
|
||||||
float drawnW = (rot == 90 || rot == 270) ? r.getHeight() * s : r.getWidth() * s;
|
|
||||||
float drawnH = (rot == 90 || rot == 270) ? r.getWidth() * s : r.getHeight() * s;
|
|
||||||
|
|
||||||
// Center in cell, accounting for CropBox offset
|
|
||||||
float tx = cellX + (cellW - drawnW) / 2f - r.getLowerLeftX() * s;
|
|
||||||
float ty = cellY + (cellH - drawnH) / 2f - r.getLowerLeftY() * s;
|
|
||||||
|
|
||||||
cs.saveGraphicsState();
|
|
||||||
cs.transform(Matrix.getTranslateInstance(tx, ty));
|
|
||||||
cs.transform(Matrix.getScaleInstance(s, s));
|
|
||||||
|
|
||||||
// Apply rotation if needed (rotate about origin), then translate to keep in cell
|
|
||||||
switch (rot) {
|
|
||||||
case 90:
|
|
||||||
cs.transform(Matrix.getRotateInstance(Math.PI / 2, 0, 0));
|
|
||||||
// After 90° CCW, the content spans x in [-r.getHeight(), 0] and y in [0,
|
|
||||||
// r.getWidth()]
|
|
||||||
cs.transform(Matrix.getTranslateInstance(0, -r.getWidth()));
|
|
||||||
break;
|
|
||||||
case 180:
|
|
||||||
cs.transform(Matrix.getRotateInstance(Math.PI, 0, 0));
|
|
||||||
cs.transform(Matrix.getTranslateInstance(-r.getWidth(), -r.getHeight()));
|
|
||||||
break;
|
|
||||||
case 270:
|
|
||||||
cs.transform(Matrix.getRotateInstance(3 * Math.PI / 2, 0, 0));
|
|
||||||
// After 270° CCW, the content spans x in [0, r.getHeight()] and y in
|
|
||||||
// [-r.getWidth(), 0]
|
|
||||||
cs.transform(Matrix.getTranslateInstance(-r.getHeight(), 0));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// 0°: no-op
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reuse LayerUtility passed from caller
|
|
||||||
PDFormXObject form = layerUtility.importPageAsForm(src, pageIndex);
|
|
||||||
cs.drawForm(form);
|
|
||||||
|
|
||||||
cs.restoreGraphicsState();
|
|
||||||
|
|
||||||
// Draw border on top of form to ensure visibility
|
|
||||||
if (addBorder) {
|
|
||||||
cs.addRect(cellX, cellY, cellW, cellH);
|
|
||||||
cs.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,26 +12,28 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
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.RequestMapping;
|
||||||
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.general.CropPdfForm;
|
import stirling.software.SPDF.model.api.general.CropPdfForm;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class CropController {
|
public class CropController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/crop", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/crop", consumes = "multipart/form-data")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Crops a PDF document",
|
summary = "Crops a PDF document",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-6
@@ -14,28 +14,30 @@ import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlin
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.JsonDataResponse;
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.EditTableOfContentsRequest;
|
import stirling.software.SPDF.model.api.EditTableOfContentsRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class EditTableOfContentsController {
|
public class EditTableOfContentsController {
|
||||||
|
|
||||||
@@ -43,7 +45,6 @@ public class EditTableOfContentsController {
|
|||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/extract-bookmarks", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/extract-bookmarks", consumes = "multipart/form-data")
|
||||||
@JsonDataResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Extract PDF Bookmarks",
|
summary = "Extract PDF Bookmarks",
|
||||||
description = "Extracts bookmarks/table of contents from a PDF document as JSON.")
|
description = "Extracts bookmarks/table of contents from a PDF document as JSON.")
|
||||||
@@ -152,7 +153,6 @@ public class EditTableOfContentsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/edit-table-of-contents", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/edit-table-of-contents", consumes = "multipart/form-data")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Edit Table of Contents",
|
summary = "Edit Table of Contents",
|
||||||
description = "Add or edit bookmarks/table of contents in a PDF document.")
|
description = "Add or edit bookmarks/table of contents in a PDF document.")
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package stirling.software.SPDF.controller.api;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
@@ -21,29 +20,30 @@ import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlin
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.general.MergePdfsRequest;
|
import stirling.software.SPDF.model.api.general.MergePdfsRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
import stirling.software.common.util.PdfErrorUtils;
|
import stirling.software.common.util.PdfErrorUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MergeController {
|
public class MergeController {
|
||||||
|
|
||||||
@@ -114,32 +114,6 @@ public class MergeController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse client file IDs from JSON string
|
|
||||||
private String[] parseClientFileIds(String clientFileIds) {
|
|
||||||
if (clientFileIds == null || clientFileIds.trim().isEmpty()) {
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// Simple JSON array parsing - remove brackets and split by comma
|
|
||||||
String trimmed = clientFileIds.trim();
|
|
||||||
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
||||||
String inside = trimmed.substring(1, trimmed.length() - 1).trim();
|
|
||||||
if (inside.isEmpty()) {
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
String[] parts = inside.split(",");
|
|
||||||
String[] result = new String[parts.length];
|
|
||||||
for (int i = 0; i < parts.length; i++) {
|
|
||||||
result[i] = parts[i].trim().replaceAll("^\"|\"$", "");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("Failed to parse client file IDs: {}", clientFileIds, e);
|
|
||||||
}
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds a table of contents to the merged document using filenames as chapter titles
|
// Adds a table of contents to the merged document using filenames as chapter titles
|
||||||
private void addTableOfContents(PDDocument mergedDocument, MultipartFile[] files) {
|
private void addTableOfContents(PDDocument mergedDocument, MultipartFile[] files) {
|
||||||
// Create the document outline
|
// Create the document outline
|
||||||
@@ -181,7 +155,6 @@ public class MergeController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/merge-pdfs")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/merge-pdfs")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Merge multiple PDF files into one",
|
summary = "Merge multiple PDF files into one",
|
||||||
description =
|
description =
|
||||||
@@ -206,48 +179,15 @@ public class MergeController {
|
|||||||
|
|
||||||
PDFMergerUtility mergerUtility = new PDFMergerUtility();
|
PDFMergerUtility mergerUtility = new PDFMergerUtility();
|
||||||
long totalSize = 0;
|
long totalSize = 0;
|
||||||
List<Integer> invalidIndexes = new ArrayList<>();
|
for (MultipartFile multipartFile : files) {
|
||||||
for (int index = 0; index < files.length; index++) {
|
|
||||||
MultipartFile multipartFile = files[index];
|
|
||||||
totalSize += multipartFile.getSize();
|
totalSize += multipartFile.getSize();
|
||||||
File tempFile =
|
File tempFile =
|
||||||
GeneralUtils.convertMultipartFileToFile(
|
GeneralUtils.convertMultipartFileToFile(
|
||||||
multipartFile); // Convert MultipartFile to File
|
multipartFile); // Convert MultipartFile to File
|
||||||
filesToDelete.add(tempFile); // Add temp file to the list for later deletion
|
filesToDelete.add(tempFile); // Add temp file to the list for later deletion
|
||||||
|
|
||||||
// Pre-validate each PDF so we can report which one(s) are broken
|
|
||||||
// Use the original MultipartFile to avoid deleting the tempFile during validation
|
|
||||||
try (PDDocument ignored = pdfDocumentFactory.load(multipartFile)) {
|
|
||||||
// OK
|
|
||||||
} catch (IOException e) {
|
|
||||||
ExceptionUtils.logException("PDF pre-validate", e);
|
|
||||||
invalidIndexes.add(index);
|
|
||||||
}
|
|
||||||
mergerUtility.addSource(tempFile); // Add source file to the merger utility
|
mergerUtility.addSource(tempFile); // Add source file to the merger utility
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!invalidIndexes.isEmpty()) {
|
|
||||||
// Parse client file IDs (always present from frontend)
|
|
||||||
String[] clientIds = parseClientFileIds(request.getClientFileIds());
|
|
||||||
|
|
||||||
// Map invalid indexes to client IDs
|
|
||||||
List<String> errorFileIds = new ArrayList<>();
|
|
||||||
for (Integer index : invalidIndexes) {
|
|
||||||
if (index < clientIds.length) {
|
|
||||||
errorFileIds.add(clientIds[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String payload =
|
|
||||||
String.format(
|
|
||||||
"{\"errorFileIds\":%s,\"message\":\"Some of the selected files can't be merged\"}",
|
|
||||||
errorFileIds.toString());
|
|
||||||
|
|
||||||
return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY)
|
|
||||||
.header("Content-Type", MediaType.APPLICATION_JSON_VALUE)
|
|
||||||
.body(payload.getBytes(StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
mergedTempFile = Files.createTempFile("merged-", ".pdf").toFile();
|
mergedTempFile = Files.createTempFile("merged-", ".pdf").toFile();
|
||||||
mergerUtility.setDestinationFileName(mergedTempFile.getAbsolutePath());
|
mergerUtility.setDestinationFileName(mergedTempFile.getAbsolutePath());
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -13,28 +13,30 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest;
|
import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MultiPageLayoutController {
|
public class MultiPageLayoutController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/multi-page-layout", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/multi-page-layout", consumes = "multipart/form-data")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Merge multiple pages of a PDF document into a single page",
|
summary = "Merge multiple pages of a PDF document into a single page",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+7
-5
@@ -6,15 +6,16 @@ import java.io.IOException;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
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.RequestMapping;
|
||||||
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.service.PdfImageRemovalService;
|
import stirling.software.SPDF.service.PdfImageRemovalService;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
@@ -23,7 +24,9 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
* Controller class for handling PDF image removal requests. Provides an endpoint to remove images
|
* Controller class for handling PDF image removal requests. Provides an endpoint to remove images
|
||||||
* from a PDF file to reduce its size.
|
* from a PDF file to reduce its size.
|
||||||
*/
|
*/
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PdfImageRemovalController {
|
public class PdfImageRemovalController {
|
||||||
|
|
||||||
@@ -44,12 +47,11 @@ public class PdfImageRemovalController {
|
|||||||
* @throws IOException If an error occurs while processing the PDF file.
|
* @throws IOException If an error occurs while processing the PDF file.
|
||||||
*/
|
*/
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-image-pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-image-pdf")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Remove images from file to reduce the file size.",
|
summary = "Remove images from file to reduce the file size.",
|
||||||
description =
|
description =
|
||||||
"This endpoint remove images from file to reduce the file size.Input:PDF"
|
"This endpoint remove images from file to reduce the file size.Input:PDF"
|
||||||
+ " Output:PDF Type:SISO")
|
+ " Output:PDF Type:MISO")
|
||||||
public ResponseEntity<byte[]> removeImages(@ModelAttribute PDFFile file) throws IOException {
|
public ResponseEntity<byte[]> removeImages(@ModelAttribute PDFFile file) throws IOException {
|
||||||
// Load the PDF document
|
// Load the PDF document
|
||||||
PDDocument document = pdfDocumentFactory.load(file);
|
PDDocument document = pdfDocumentFactory.load(file);
|
||||||
|
|||||||
+6
-4
@@ -15,29 +15,31 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.general.OverlayPdfsRequest;
|
import stirling.software.SPDF.model.api.general.OverlayPdfsRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PdfOverlayController {
|
public class PdfOverlayController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Overlay PDF files in various modes",
|
summary = "Overlay PDF files in various modes",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-5
@@ -9,34 +9,36 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
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;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RearrangePagesPDFController {
|
public class RearrangePagesPDFController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-pages")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-pages")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Remove pages from a PDF file",
|
summary = "Remove pages from a PDF file",
|
||||||
description =
|
description =
|
||||||
@@ -236,7 +238,6 @@ public class RearrangePagesPDFController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/rearrange-pages")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/rearrange-pages")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Rearrange pages in a PDF file",
|
summary = "Rearrange pages in a PDF file",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -7,29 +7,31 @@ import org.apache.pdfbox.pdmodel.PDPage;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.general.RotatePDFRequest;
|
import stirling.software.SPDF.model.api.general.RotatePDFRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RotationController {
|
public class RotationController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/rotate-pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/rotate-pdf")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Rotate a PDF file",
|
summary = "Rotate a PDF file",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -14,29 +14,31 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.general.ScalePagesRequest;
|
import stirling.software.SPDF.model.api.general.ScalePagesRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ScalePagesController {
|
public class ScalePagesController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/scale-pages", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/scale-pages", consumes = "multipart/form-data")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Change the size of a PDF page/document",
|
summary = "Change the size of a PDF page/document",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-2
@@ -5,21 +5,25 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Hidden;
|
import io.swagger.v3.oas.annotations.Hidden;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.SettingsApi;
|
|
||||||
import stirling.software.common.configuration.InstallationPathConfig;
|
import stirling.software.common.configuration.InstallationPathConfig;
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
|
|
||||||
@SettingsApi
|
@Controller
|
||||||
|
@Tag(name = "Settings", description = "Settings APIs")
|
||||||
|
@RequestMapping("/api/v1/settings")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Hidden
|
@Hidden
|
||||||
public class SettingsController {
|
public class SettingsController {
|
||||||
|
|||||||
+6
-4
@@ -15,31 +15,33 @@ import org.apache.pdfbox.pdmodel.PDPage;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.MultiFileResponse;
|
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SplitPDFController {
|
public class SplitPDFController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/split-pages")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/split-pages")
|
||||||
@MultiFileResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Split a PDF file into separate documents",
|
summary = "Split a PDF file into separate documents",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -15,10 +15,13 @@ import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlin
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -27,18 +30,18 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.MultiFileResponse;
|
|
||||||
import stirling.software.SPDF.model.api.SplitPdfByChaptersRequest;
|
import stirling.software.SPDF.model.api.SplitPdfByChaptersRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.model.PdfMetadata;
|
import stirling.software.common.model.PdfMetadata;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.service.PdfMetadataService;
|
import stirling.software.common.service.PdfMetadataService;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SplitPdfByChaptersController {
|
public class SplitPdfByChaptersController {
|
||||||
|
|
||||||
@@ -115,7 +118,6 @@ public class SplitPdfByChaptersController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/split-pdf-by-chapters", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/split-pdf-by-chapters", consumes = "multipart/form-data")
|
||||||
@MultiFileResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Split PDFs by Chapters",
|
summary = "Split PDFs by Chapters",
|
||||||
description = "Splits a PDF into chapters and returns a ZIP file.")
|
description = "Splits a PDF into chapters and returns a ZIP file.")
|
||||||
|
|||||||
+6
-4
@@ -20,28 +20,30 @@ import org.apache.pdfbox.util.Matrix;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.MultiFileResponse;
|
|
||||||
import stirling.software.SPDF.model.api.SplitPdfBySectionsRequest;
|
import stirling.software.SPDF.model.api.SplitPdfBySectionsRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SplitPdfBySectionsController {
|
public class SplitPdfBySectionsController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data")
|
||||||
@MultiFileResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Split PDF pages into smaller sections",
|
summary = "Split PDF pages into smaller sections",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -12,32 +12,34 @@ import org.apache.pdfbox.pdmodel.PDPage;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.MultiFileResponse;
|
|
||||||
import stirling.software.SPDF.model.api.general.SplitPdfBySizeOrCountRequest;
|
import stirling.software.SPDF.model.api.general.SplitPdfBySizeOrCountRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SplitPdfBySizeController {
|
public class SplitPdfBySizeController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data")
|
||||||
@MultiFileResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Auto split PDF pages into separate documents based on size or count",
|
summary = "Auto split PDF pages into separate documents based on size or count",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -12,26 +12,28 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
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.RequestMapping;
|
||||||
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.GeneralApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@GeneralApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/general")
|
||||||
|
@Tag(name = "General", description = "General APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ToSinglePageController {
|
public class ToSinglePageController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf-to-single-page")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf-to-single-page")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert a multi-page PDF into a single long page PDF",
|
summary = "Convert a multi-page PDF into a single long page PDF",
|
||||||
description =
|
description =
|
||||||
|
|||||||
@@ -15,11 +15,14 @@ import org.springframework.core.io.Resource;
|
|||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -27,7 +30,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import stirling.software.SPDF.model.Dependency;
|
import stirling.software.SPDF.model.Dependency;
|
||||||
import stirling.software.SPDF.model.SignatureFile;
|
import stirling.software.SPDF.model.SignatureFile;
|
||||||
import stirling.software.SPDF.service.SignatureService;
|
import stirling.software.SPDF.service.SignatureService;
|
||||||
import stirling.software.common.annotations.api.UiDataApi;
|
|
||||||
import stirling.software.common.configuration.InstallationPathConfig;
|
import stirling.software.common.configuration.InstallationPathConfig;
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
@@ -36,7 +38,9 @@ import stirling.software.common.util.ExceptionUtils;
|
|||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@UiDataApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/ui-data")
|
||||||
|
@Tag(name = "UI Data", description = "APIs for React UI data")
|
||||||
public class UIDataController {
|
public class UIDataController {
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|||||||
+6
-4
@@ -8,17 +8,18 @@ import org.springframework.http.HttpStatus;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.ConvertApi;
|
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
import stirling.software.common.model.api.converters.EmlToPdfRequest;
|
import stirling.software.common.model.api.converters.EmlToPdfRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -27,7 +28,9 @@ import stirling.software.common.util.EmlToPdf;
|
|||||||
import stirling.software.common.util.TempFileManager;
|
import stirling.software.common.util.TempFileManager;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@ConvertApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/convert")
|
||||||
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ConvertEmlToPDF {
|
public class ConvertEmlToPDF {
|
||||||
@@ -38,7 +41,6 @@ public class ConvertEmlToPDF {
|
|||||||
private final CustomHtmlSanitizer customHtmlSanitizer;
|
private final CustomHtmlSanitizer customHtmlSanitizer;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/eml/pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/eml/pdf")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert EML to PDF",
|
summary = "Convert EML to PDF",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -2,16 +2,17 @@ package stirling.software.SPDF.controller.api.converters;
|
|||||||
|
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.ConvertApi;
|
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
import stirling.software.common.model.api.converters.HTMLToPdfRequest;
|
import stirling.software.common.model.api.converters.HTMLToPdfRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -21,7 +22,9 @@ import stirling.software.common.util.FileToPdf;
|
|||||||
import stirling.software.common.util.TempFileManager;
|
import stirling.software.common.util.TempFileManager;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@ConvertApi
|
@RestController
|
||||||
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
|
@RequestMapping("/api/v1/convert")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ConvertHtmlToPDF {
|
public class ConvertHtmlToPDF {
|
||||||
|
|
||||||
@@ -34,7 +37,6 @@ public class ConvertHtmlToPDF {
|
|||||||
private final CustomHtmlSanitizer customHtmlSanitizer;
|
private final CustomHtmlSanitizer customHtmlSanitizer;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert an HTML or ZIP (containing HTML and CSS) to PDF",
|
summary = "Convert an HTML or ZIP (containing HTML and CSS) to PDF",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-6
@@ -19,20 +19,20 @@ import org.apache.pdfbox.rendering.ImageType;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.MultiFileResponse;
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
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.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.ConvertApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.CheckProgramInstall;
|
import stirling.software.common.util.CheckProgramInstall;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
@@ -42,15 +42,16 @@ import stirling.software.common.util.ProcessExecutor;
|
|||||||
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@ConvertApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/convert")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ConvertImgPDFController {
|
public class ConvertImgPDFController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/img")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/img")
|
||||||
@MultiFileResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert PDF to image(s)",
|
summary = "Convert PDF to image(s)",
|
||||||
description =
|
description =
|
||||||
@@ -211,7 +212,6 @@ public class ConvertImgPDFController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/img/pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/img/pdf")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert images to a PDF file",
|
summary = "Convert images to a PDF file",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -12,16 +12,17 @@ import org.commonmark.renderer.html.AttributeProvider;
|
|||||||
import org.commonmark.renderer.html.HtmlRenderer;
|
import org.commonmark.renderer.html.HtmlRenderer;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.ConvertApi;
|
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
import stirling.software.common.model.api.GeneralFile;
|
import stirling.software.common.model.api.GeneralFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -31,7 +32,9 @@ import stirling.software.common.util.FileToPdf;
|
|||||||
import stirling.software.common.util.TempFileManager;
|
import stirling.software.common.util.TempFileManager;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@ConvertApi
|
@RestController
|
||||||
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
|
@RequestMapping("/api/v1/convert")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ConvertMarkdownToPdf {
|
public class ConvertMarkdownToPdf {
|
||||||
|
|
||||||
@@ -43,7 +46,6 @@ public class ConvertMarkdownToPdf {
|
|||||||
private final CustomHtmlSanitizer customHtmlSanitizer;
|
private final CustomHtmlSanitizer customHtmlSanitizer;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert a Markdown file to PDF",
|
summary = "Convert a Markdown file to PDF",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-2
@@ -13,15 +13,17 @@ import org.apache.commons.io.FilenameUtils;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.ConvertApi;
|
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
import stirling.software.common.model.api.GeneralFile;
|
import stirling.software.common.model.api.GeneralFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -30,7 +32,9 @@ import stirling.software.common.util.ProcessExecutor;
|
|||||||
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@ConvertApi
|
@RestController
|
||||||
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
|
@RequestMapping("/api/v1/convert")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ConvertOfficeController {
|
public class ConvertOfficeController {
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -2,17 +2,20 @@ package stirling.software.SPDF.controller.api.converters;
|
|||||||
|
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.HtmlConversionResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.ConvertApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.util.PDFToFile;
|
import stirling.software.common.util.PDFToFile;
|
||||||
|
|
||||||
@ConvertApi
|
@RestController
|
||||||
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
|
@RequestMapping("/api/v1/convert")
|
||||||
public class ConvertPDFToHtml {
|
public class ConvertPDFToHtml {
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/html")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/html")
|
||||||
@@ -20,7 +23,6 @@ public class ConvertPDFToHtml {
|
|||||||
summary = "Convert PDF to HTML",
|
summary = "Convert PDF to HTML",
|
||||||
description =
|
description =
|
||||||
"This endpoint converts a PDF file to HTML format. Input:PDF Output:HTML Type:SISO")
|
"This endpoint converts a PDF file to HTML format. Input:PDF Output:HTML Type:SISO")
|
||||||
@HtmlConversionResponse
|
|
||||||
public ResponseEntity<byte[]> processPdfToHTML(@ModelAttribute PDFFile file) throws Exception {
|
public ResponseEntity<byte[]> processPdfToHTML(@ModelAttribute PDFFile file) throws Exception {
|
||||||
MultipartFile inputFile = file.getFileInput();
|
MultipartFile inputFile = file.getFileInput();
|
||||||
PDFToFile pdfToFile = new PDFToFile();
|
PDFToFile pdfToFile = new PDFToFile();
|
||||||
|
|||||||
+6
-10
@@ -7,35 +7,34 @@ import org.apache.pdfbox.text.PDFTextStripper;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.PowerPointConversionResponse;
|
|
||||||
import stirling.software.SPDF.config.swagger.TextPlainConversionResponse;
|
|
||||||
import stirling.software.SPDF.config.swagger.WordConversionResponse;
|
|
||||||
import stirling.software.SPDF.config.swagger.XmlConversionResponse;
|
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToPresentationRequest;
|
import stirling.software.SPDF.model.api.converters.PdfToPresentationRequest;
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToTextOrRTFRequest;
|
import stirling.software.SPDF.model.api.converters.PdfToTextOrRTFRequest;
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToWordRequest;
|
import stirling.software.SPDF.model.api.converters.PdfToWordRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.ConvertApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.PDFToFile;
|
import stirling.software.common.util.PDFToFile;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@ConvertApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/convert")
|
||||||
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ConvertPDFToOffice {
|
public class ConvertPDFToOffice {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/presentation")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/presentation")
|
||||||
@PowerPointConversionResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert PDF to Presentation format",
|
summary = "Convert PDF to Presentation format",
|
||||||
description =
|
description =
|
||||||
@@ -51,7 +50,6 @@ public class ConvertPDFToOffice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/text")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/text")
|
||||||
@TextPlainConversionResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert PDF to Text or RTF format",
|
summary = "Convert PDF to Text or RTF format",
|
||||||
description =
|
description =
|
||||||
@@ -80,7 +78,6 @@ public class ConvertPDFToOffice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/word")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/word")
|
||||||
@WordConversionResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert PDF to Word document",
|
summary = "Convert PDF to Word document",
|
||||||
description =
|
description =
|
||||||
@@ -95,7 +92,6 @@ public class ConvertPDFToOffice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/xml")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/xml")
|
||||||
@XmlConversionResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert PDF to XML",
|
summary = "Convert PDF to XML",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -55,28 +55,30 @@ import org.apache.xmpbox.xml.XmpSerializer;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToPdfARequest;
|
import stirling.software.SPDF.model.api.converters.PdfToPdfARequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.ConvertApi;
|
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.ProcessExecutor;
|
import stirling.software.common.util.ProcessExecutor;
|
||||||
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@ConvertApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/convert")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
public class ConvertPDFToPDFA {
|
public class ConvertPDFToPDFA {
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/pdfa")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/pdf/pdfa")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert a PDF to a PDF/A",
|
summary = "Convert a PDF to a PDF/A",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -9,16 +9,17 @@ import java.util.List;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
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.RequestMapping;
|
||||||
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.ConvertApi;
|
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -28,8 +29,10 @@ import stirling.software.common.util.ProcessExecutor;
|
|||||||
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@ConvertApi
|
@RestController
|
||||||
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@RequestMapping("/api/v1/convert")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ConvertWebsiteToPDF {
|
public class ConvertWebsiteToPDF {
|
||||||
|
|
||||||
@@ -38,7 +41,6 @@ public class ConvertWebsiteToPDF {
|
|||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/url/pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/url/pdf")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert a URL to a PDF",
|
summary = "Convert a URL to a PDF",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -18,17 +18,18 @@ import org.springframework.http.HttpHeaders;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.CsvConversionResponse;
|
|
||||||
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 stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.ConvertApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
|
|
||||||
import technology.tabula.ObjectExtractor;
|
import technology.tabula.ObjectExtractor;
|
||||||
@@ -36,7 +37,9 @@ import technology.tabula.Page;
|
|||||||
import technology.tabula.Table;
|
import technology.tabula.Table;
|
||||||
import technology.tabula.extractors.SpreadsheetExtractionAlgorithm;
|
import technology.tabula.extractors.SpreadsheetExtractionAlgorithm;
|
||||||
|
|
||||||
@ConvertApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/convert")
|
||||||
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ExtractCSVController {
|
public class ExtractCSVController {
|
||||||
@@ -44,7 +47,6 @@ public class ExtractCSVController {
|
|||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
|
||||||
@CsvConversionResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Extracts a CSV document from a PDF",
|
summary = "Extracts a CSV document from a PDF",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-9
@@ -7,14 +7,16 @@ import org.apache.pdfbox.pdmodel.PDPage;
|
|||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.FilterResponse;
|
|
||||||
import stirling.software.SPDF.model.api.PDFComparisonAndCount;
|
import stirling.software.SPDF.model.api.PDFComparisonAndCount;
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
import stirling.software.SPDF.model.api.filter.ContainsTextRequest;
|
import stirling.software.SPDF.model.api.filter.ContainsTextRequest;
|
||||||
@@ -22,20 +24,20 @@ import stirling.software.SPDF.model.api.filter.FileSizeRequest;
|
|||||||
import stirling.software.SPDF.model.api.filter.PageRotationRequest;
|
import stirling.software.SPDF.model.api.filter.PageRotationRequest;
|
||||||
import stirling.software.SPDF.model.api.filter.PageSizeRequest;
|
import stirling.software.SPDF.model.api.filter.PageSizeRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.FilterApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.PdfUtils;
|
import stirling.software.common.util.PdfUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@FilterApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/filter")
|
||||||
|
@Tag(name = "Filter", description = "Filter APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class FilterController {
|
public class FilterController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-contains-text")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-contains-text")
|
||||||
@FilterResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Checks if a PDF contains set text, returns true if does",
|
summary = "Checks if a PDF contains set text, returns true if does",
|
||||||
description = "Input:PDF Output:Boolean Type:SISO")
|
description = "Input:PDF Output:Boolean Type:SISO")
|
||||||
@@ -54,7 +56,6 @@ public class FilterController {
|
|||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-contains-image")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-contains-image")
|
||||||
@FilterResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Checks if a PDF contains an image",
|
summary = "Checks if a PDF contains an image",
|
||||||
description = "Input:PDF Output:Boolean Type:SISO")
|
description = "Input:PDF Output:Boolean Type:SISO")
|
||||||
@@ -71,7 +72,6 @@ public class FilterController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-page-count")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-page-count")
|
||||||
@FilterResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Checks if a PDF is greater, less or equal to a setPageCount",
|
summary = "Checks if a PDF is greater, less or equal to a setPageCount",
|
||||||
description = "Input:PDF Output:Boolean Type:SISO")
|
description = "Input:PDF Output:Boolean Type:SISO")
|
||||||
@@ -105,7 +105,6 @@ public class FilterController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-page-size")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-page-size")
|
||||||
@FilterResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Checks if a PDF is of a certain size",
|
summary = "Checks if a PDF is of a certain size",
|
||||||
description = "Input:PDF Output:Boolean Type:SISO")
|
description = "Input:PDF Output:Boolean Type:SISO")
|
||||||
@@ -149,7 +148,6 @@ public class FilterController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-file-size")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-file-size")
|
||||||
@FilterResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Checks if a PDF is a set file size",
|
summary = "Checks if a PDF is a set file size",
|
||||||
description = "Input:PDF Output:Boolean Type:SISO")
|
description = "Input:PDF Output:Boolean Type:SISO")
|
||||||
@@ -183,7 +181,6 @@ public class FilterController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-page-rotation")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/filter-page-rotation")
|
||||||
@FilterResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Checks if a PDF is of a certain rotation",
|
summary = "Checks if a PDF is of a certain rotation",
|
||||||
description = "Input:PDF Output:Boolean Type:SISO")
|
description = "Input:PDF Output:Boolean Type:SISO")
|
||||||
|
|||||||
+6
-4
@@ -6,25 +6,28 @@ import java.util.List;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.misc.AddAttachmentRequest;
|
import stirling.software.SPDF.model.api.misc.AddAttachmentRequest;
|
||||||
import stirling.software.SPDF.service.AttachmentServiceInterface;
|
import stirling.software.SPDF.service.AttachmentServiceInterface;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@RestController
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
public class AttachmentController {
|
public class AttachmentController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
@@ -32,7 +35,6 @@ public class AttachmentController {
|
|||||||
private final AttachmentServiceInterface pdfAttachmentService;
|
private final AttachmentServiceInterface pdfAttachmentService;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-attachments")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-attachments")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Add attachments to PDF",
|
summary = "Add attachments to PDF",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-2
@@ -10,22 +10,26 @@ import org.apache.pdfbox.text.PDFTextStripper;
|
|||||||
import org.apache.pdfbox.text.TextPosition;
|
import org.apache.pdfbox.text.TextPosition;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
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.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AutoRenameController {
|
public class AutoRenameController {
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -19,6 +19,8 @@ import org.apache.pdfbox.rendering.PDFRenderer;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import com.google.zxing.*;
|
import com.google.zxing.*;
|
||||||
@@ -26,19 +28,20 @@ import com.google.zxing.common.HybridBinarizer;
|
|||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.MultiFileResponse;
|
|
||||||
import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest;
|
import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AutoSplitPdfController {
|
public class AutoSplitPdfController {
|
||||||
|
|
||||||
@@ -100,7 +103,6 @@ public class AutoSplitPdfController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data")
|
||||||
@MultiFileResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Auto split PDF pages into separate documents",
|
summary = "Auto split PDF pages into separate documents",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-2
@@ -17,23 +17,27 @@ import org.springframework.http.HttpStatus;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
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.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.PdfUtils;
|
import stirling.software.common.util.PdfUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class BlankPageController {
|
public class BlankPageController {
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -34,10 +34,13 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -47,10 +50,8 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
|
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
@@ -58,8 +59,10 @@ import stirling.software.common.util.ProcessExecutor;
|
|||||||
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class CompressController {
|
public class CompressController {
|
||||||
|
|
||||||
@@ -656,7 +659,6 @@ public class CompressController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/compress-pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/compress-pdf")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Optimize PDF file",
|
summary = "Optimize PDF file",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+9
-21
@@ -6,36 +6,29 @@ import java.util.Map;
|
|||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Hidden;
|
import io.swagger.v3.oas.annotations.Hidden;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||||
import stirling.software.common.annotations.api.ConfigApi;
|
|
||||||
import stirling.software.common.configuration.AppConfig;
|
import stirling.software.common.configuration.AppConfig;
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
import stirling.software.common.service.ServerCertificateServiceInterface;
|
|
||||||
|
|
||||||
@ConfigApi
|
@RestController
|
||||||
|
@Tag(name = "Config", description = "Configuration APIs")
|
||||||
|
@RequestMapping("/api/v1/config")
|
||||||
|
@RequiredArgsConstructor
|
||||||
@Hidden
|
@Hidden
|
||||||
public class ConfigController {
|
public class ConfigController {
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
private final ApplicationContext applicationContext;
|
private final ApplicationContext applicationContext;
|
||||||
private final EndpointConfiguration endpointConfiguration;
|
private final EndpointConfiguration endpointConfiguration;
|
||||||
private final ServerCertificateServiceInterface serverCertificateService;
|
|
||||||
|
|
||||||
public ConfigController(
|
|
||||||
ApplicationProperties applicationProperties,
|
|
||||||
ApplicationContext applicationContext,
|
|
||||||
EndpointConfiguration endpointConfiguration,
|
|
||||||
@org.springframework.beans.factory.annotation.Autowired(required = false)
|
|
||||||
ServerCertificateServiceInterface serverCertificateService) {
|
|
||||||
this.applicationProperties = applicationProperties;
|
|
||||||
this.applicationContext = applicationContext;
|
|
||||||
this.endpointConfiguration = endpointConfiguration;
|
|
||||||
this.serverCertificateService = serverCertificateService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/app-config")
|
@GetMapping("/app-config")
|
||||||
public ResponseEntity<Map<String, Object>> getAppConfig() {
|
public ResponseEntity<Map<String, Object>> getAppConfig() {
|
||||||
@@ -69,11 +62,6 @@ public class ConfigController {
|
|||||||
// Premium/Enterprise settings
|
// Premium/Enterprise settings
|
||||||
configData.put("premiumEnabled", applicationProperties.getPremium().isEnabled());
|
configData.put("premiumEnabled", applicationProperties.getPremium().isEnabled());
|
||||||
|
|
||||||
// Server certificate settings
|
|
||||||
configData.put(
|
|
||||||
"serverCertificateEnabled",
|
|
||||||
serverCertificateService != null && serverCertificateService.isEnabled());
|
|
||||||
|
|
||||||
// Legal settings
|
// Legal settings
|
||||||
configData.put(
|
configData.put(
|
||||||
"termsAndConditions", applicationProperties.getLegal().getTermsAndConditions());
|
"termsAndConditions", applicationProperties.getLegal().getTermsAndConditions());
|
||||||
|
|||||||
+6
-2
@@ -13,22 +13,26 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class DecompressPdfController {
|
public class DecompressPdfController {
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -19,17 +19,18 @@ import org.apache.pdfbox.rendering.PDFRenderer;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.MultiFileResponse;
|
|
||||||
import stirling.software.SPDF.model.api.misc.ExtractImageScansRequest;
|
import stirling.software.SPDF.model.api.misc.ExtractImageScansRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.CheckProgramInstall;
|
import stirling.software.common.util.CheckProgramInstall;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
@@ -38,8 +39,10 @@ import stirling.software.common.util.ProcessExecutor;
|
|||||||
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ExtractImageScansController {
|
public class ExtractImageScansController {
|
||||||
|
|
||||||
@@ -48,7 +51,6 @@ public class ExtractImageScansController {
|
|||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/extract-image-scans")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/extract-image-scans")
|
||||||
@MultiFileResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Extract image scans from an input file",
|
summary = "Extract image scans from an input file",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -27,32 +27,34 @@ import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.MultiFileResponse;
|
|
||||||
import stirling.software.SPDF.model.api.PDFExtractImagesRequest;
|
import stirling.software.SPDF.model.api.PDFExtractImagesRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.ImageProcessingUtils;
|
import stirling.software.common.util.ImageProcessingUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ExtractImagesController {
|
public class ExtractImagesController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/extract-images")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/extract-images")
|
||||||
@MultiFileResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Extract images from a PDF file",
|
summary = "Extract images from a PDF file",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -13,30 +13,32 @@ import org.apache.pdfbox.rendering.ImageType;
|
|||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.misc.FlattenRequest;
|
import stirling.software.SPDF.model.api.misc.FlattenRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class FlattenController {
|
public class FlattenController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/flatten")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/flatten")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Flatten PDF form fields or full page",
|
summary = "Flatten PDF form fields or full page",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+4
-4
@@ -17,20 +17,21 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.misc.MetadataRequest;
|
import stirling.software.SPDF.model.api.misc.MetadataRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
import stirling.software.common.util.propertyeditor.StringToMapPropertyEditor;
|
import stirling.software.common.util.propertyeditor.StringToMapPropertyEditor;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MetadataController {
|
public class MetadataController {
|
||||||
|
|
||||||
@@ -52,7 +53,6 @@ public class MetadataController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/update-metadata")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/update-metadata")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Update metadata of a PDF file",
|
summary = "Update metadata of a PDF file",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-4
@@ -18,19 +18,20 @@ import org.apache.pdfbox.text.PDFTextStripper;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.misc.ProcessPdfWithOcrRequest;
|
import stirling.software.SPDF.model.api.misc.ProcessPdfWithOcrRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.model.ApplicationProperties;
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
@@ -41,7 +42,9 @@ import stirling.software.common.util.TempFile;
|
|||||||
import stirling.software.common.util.TempFileManager;
|
import stirling.software.common.util.TempFileManager;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class OCRController {
|
public class OCRController {
|
||||||
@@ -74,7 +77,6 @@ public class OCRController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/ocr-pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/ocr-pdf")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Process a PDF file with OCR",
|
summary = "Process a PDF file with OCR",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-2
@@ -5,23 +5,27 @@ import java.io.IOException;
|
|||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
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.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.PdfUtils;
|
import stirling.software.common.util.PdfUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class OverlayImageController {
|
public class OverlayImageController {
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -13,29 +13,31 @@ import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.misc.AddPageNumbersRequest;
|
import stirling.software.SPDF.model.api.misc.AddPageNumbersRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PageNumbersController {
|
public class PageNumbersController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/add-page-numbers", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/add-page-numbers", consumes = "multipart/form-data")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Add page numbers to a PDF document",
|
summary = "Add page numbers to a PDF document",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+7
-2
@@ -20,14 +20,19 @@ import org.apache.pdfbox.printing.PDFPageable;
|
|||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
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;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PrintFileController {
|
public class PrintFileController {
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -6,18 +6,19 @@ import java.util.List;
|
|||||||
|
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ProcessExecutor;
|
import stirling.software.common.util.ProcessExecutor;
|
||||||
@@ -26,7 +27,9 @@ import stirling.software.common.util.TempFile;
|
|||||||
import stirling.software.common.util.TempFileManager;
|
import stirling.software.common.util.TempFileManager;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RepairController {
|
public class RepairController {
|
||||||
@@ -44,7 +47,6 @@ public class RepairController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/repair")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/repair")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Repair a PDF file",
|
summary = "Repair a PDF file",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-2
@@ -7,17 +7,21 @@ import org.springframework.http.HttpHeaders;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.ReplaceAndInvertColorRequest;
|
import stirling.software.SPDF.model.api.misc.ReplaceAndInvertColorRequest;
|
||||||
import stirling.software.SPDF.service.misc.ReplaceAndInvertColorService;
|
import stirling.software.SPDF.service.misc.ReplaceAndInvertColorService;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ReplaceAndInvertColorController {
|
public class ReplaceAndInvertColorController {
|
||||||
|
|
||||||
|
|||||||
+6
-2
@@ -19,10 +19,13 @@ import org.apache.pdfbox.rendering.PDFRenderer;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
@@ -31,11 +34,12 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.ScannerEffectRequest;
|
import stirling.software.SPDF.model.api.misc.ScannerEffectRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous PDF APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ScannerEffectController {
|
public class ScannerEffectController {
|
||||||
|
|||||||
+6
-4
@@ -9,28 +9,30 @@ import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.JavaScriptResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ShowJavascript {
|
public class ShowJavascript {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/show-javascript")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/show-javascript")
|
||||||
@JavaScriptResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Grabs all JS from a PDF and returns a single JS file with all code",
|
summary = "Grabs all JS from a PDF and returns a single JS file with all code",
|
||||||
description = "desc. Input:PDF Output:JS Type:SISO")
|
description = "desc. Input:PDF Output:JS Type:SISO")
|
||||||
|
|||||||
+21
-47
@@ -26,23 +26,26 @@ import org.apache.pdfbox.util.Matrix;
|
|||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.misc.AddStampRequest;
|
import stirling.software.SPDF.model.api.misc.AddStampRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.TempFile;
|
import stirling.software.common.util.TempFile;
|
||||||
import stirling.software.common.util.TempFileManager;
|
import stirling.software.common.util.TempFileManager;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class StampController {
|
public class StampController {
|
||||||
|
|
||||||
@@ -50,7 +53,6 @@ public class StampController {
|
|||||||
private final TempFileManager tempFileManager;
|
private final TempFileManager tempFileManager;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-stamp")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-stamp")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Add stamp to a PDF file",
|
summary = "Add stamp to a PDF file",
|
||||||
description =
|
description =
|
||||||
@@ -237,54 +239,34 @@ public class StampController {
|
|||||||
|
|
||||||
PDRectangle pageSize = page.getMediaBox();
|
PDRectangle pageSize = page.getMediaBox();
|
||||||
float x, y;
|
float x, y;
|
||||||
// Split the stampText into multiple lines
|
|
||||||
String[] lines = stampText.split("\\r?\\n|\\\\n");
|
|
||||||
|
|
||||||
// Calculate dynamic line height based on font ascent and descent
|
|
||||||
float ascent = font.getFontDescriptor().getAscent();
|
|
||||||
float descent = font.getFontDescriptor().getDescent();
|
|
||||||
float lineHeight = ((ascent - descent) / 1000) * fontSize;
|
|
||||||
|
|
||||||
// Compute a single pivot for the entire text block to avoid line-by-line wobble
|
|
||||||
float capHeight = calculateTextCapHeight(font, fontSize);
|
|
||||||
float blockHeight = Math.max(lineHeight, lineHeight * Math.max(1, lines.length));
|
|
||||||
float maxWidth = 0f;
|
|
||||||
for (String ln : lines) {
|
|
||||||
maxWidth = Math.max(maxWidth, calculateTextWidth(ln, font, fontSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overrideX >= 0 && overrideY >= 0) {
|
if (overrideX >= 0 && overrideY >= 0) {
|
||||||
// Use override values if provided
|
// Use override values if provided
|
||||||
x = overrideX;
|
x = overrideX;
|
||||||
y = overrideY;
|
y = overrideY;
|
||||||
} else {
|
} else {
|
||||||
// Base positioning on the true multi-line block size
|
x = calculatePositionX(pageSize, position, fontSize, font, fontSize, stampText, margin);
|
||||||
x = calculatePositionX(pageSize, position, maxWidth, null, 0, null, margin);
|
y =
|
||||||
y = calculatePositionY(pageSize, position, blockHeight, margin);
|
calculatePositionY(
|
||||||
|
pageSize, position, calculateTextCapHeight(font, fontSize), margin);
|
||||||
}
|
}
|
||||||
|
// Split the stampText into multiple lines
|
||||||
|
String[] lines = stampText.split("\\\\n");
|
||||||
|
|
||||||
// After anchoring the block, draw from the top line downward
|
// Calculate dynamic line height based on font ascent and descent
|
||||||
float adjustedX = x;
|
float ascent = font.getFontDescriptor().getAscent();
|
||||||
float adjustedY = y;
|
float descent = font.getFontDescriptor().getDescent();
|
||||||
float pivotX = adjustedX + maxWidth / 2f;
|
float lineHeight = ((ascent - descent) / 1000) * fontSize;
|
||||||
float pivotY = adjustedY + blockHeight / 2f;
|
|
||||||
|
|
||||||
// Apply rotation about the block center at the graphics state level
|
|
||||||
contentStream.saveGraphicsState();
|
|
||||||
contentStream.transform(Matrix.getTranslateInstance(pivotX, pivotY));
|
|
||||||
contentStream.transform(Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0));
|
|
||||||
contentStream.transform(Matrix.getTranslateInstance(-pivotX, -pivotY));
|
|
||||||
|
|
||||||
contentStream.beginText();
|
contentStream.beginText();
|
||||||
for (int i = 0; i < lines.length; i++) {
|
for (int i = 0; i < lines.length; i++) {
|
||||||
String line = lines[i];
|
String line = lines[i];
|
||||||
// Start from top line: yTop = adjustedY + blockHeight - capHeight
|
// Set the text matrix for each line with rotation
|
||||||
float yLine = adjustedY + blockHeight - capHeight - (i * lineHeight);
|
contentStream.setTextMatrix(
|
||||||
contentStream.setTextMatrix(Matrix.getTranslateInstance(adjustedX, yLine));
|
Matrix.getRotateInstance(Math.toRadians(rotation), x, y - (i * lineHeight)));
|
||||||
contentStream.showText(line);
|
contentStream.showText(line);
|
||||||
}
|
}
|
||||||
contentStream.endText();
|
contentStream.endText();
|
||||||
contentStream.restoreGraphicsState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addImageStamp(
|
private void addImageStamp(
|
||||||
@@ -328,17 +310,9 @@ public class StampController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
contentStream.saveGraphicsState();
|
contentStream.saveGraphicsState();
|
||||||
// Rotate and scale about the center of the image
|
contentStream.transform(Matrix.getTranslateInstance(x, y));
|
||||||
float centerX = x + (desiredPhysicalWidth / 2f);
|
|
||||||
float centerY = y + (desiredPhysicalHeight / 2f);
|
|
||||||
contentStream.transform(Matrix.getTranslateInstance(centerX, centerY));
|
|
||||||
contentStream.transform(Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0));
|
contentStream.transform(Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0));
|
||||||
contentStream.drawImage(
|
contentStream.drawImage(xobject, 0, 0, desiredPhysicalWidth, desiredPhysicalHeight);
|
||||||
xobject,
|
|
||||||
-desiredPhysicalWidth / 2f,
|
|
||||||
-desiredPhysicalHeight / 2f,
|
|
||||||
desiredPhysicalWidth,
|
|
||||||
desiredPhysicalHeight);
|
|
||||||
contentStream.restoreGraphicsState();
|
contentStream.restoreGraphicsState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -12,21 +12,24 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.MiscApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@MiscApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/misc")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
public class UnlockPDFFormsController {
|
public class UnlockPDFFormsController {
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@@ -35,7 +38,6 @@ public class UnlockPDFFormsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/unlock-pdf-forms")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/unlock-pdf-forms")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Remove read-only property from form fields",
|
summary = "Remove read-only property from form fields",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+6
-11
@@ -12,29 +12,31 @@ import org.springframework.core.io.Resource;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.MultiFileResponse;
|
|
||||||
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;
|
||||||
import stirling.software.SPDF.model.api.HandleDataRequest;
|
import stirling.software.SPDF.model.api.HandleDataRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.PipelineApi;
|
|
||||||
import stirling.software.common.service.PostHogService;
|
import stirling.software.common.service.PostHogService;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@PipelineApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/pipeline")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Pipeline", description = "Pipeline APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PipelineController {
|
public class PipelineController {
|
||||||
|
|
||||||
@@ -45,13 +47,6 @@ public class PipelineController {
|
|||||||
private final PostHogService postHogService;
|
private final PostHogService postHogService;
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/handleData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
@AutoJobPostMapping(value = "/handleData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
@MultiFileResponse
|
|
||||||
@Operation(
|
|
||||||
summary = "Execute automated PDF processing pipeline",
|
|
||||||
description =
|
|
||||||
"This endpoint processes multiple PDF files through a configurable pipeline of operations. "
|
|
||||||
+ "Users provide files and a JSON configuration defining the sequence of operations to perform. "
|
|
||||||
+ "Input:PDF Output:PDF/ZIP Type:MIMO")
|
|
||||||
public ResponseEntity<byte[]> handleData(@ModelAttribute HandleDataRequest request)
|
public ResponseEntity<byte[]> handleData(@ModelAttribute HandleDataRequest request)
|
||||||
throws JsonMappingException, JsonProcessingException {
|
throws JsonMappingException, JsonProcessingException {
|
||||||
MultipartFile[] files = request.getFileInput();
|
MultipartFile[] files = request.getFileInput();
|
||||||
|
|||||||
+3
-33
@@ -53,7 +53,6 @@ import org.bouncycastle.operator.InputDecryptorProvider;
|
|||||||
import org.bouncycastle.operator.OperatorCreationException;
|
import org.bouncycastle.operator.OperatorCreationException;
|
||||||
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
|
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
|
||||||
import org.bouncycastle.pkcs.PKCSException;
|
import org.bouncycastle.pkcs.PKCSException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -69,13 +68,12 @@ import io.micrometer.common.util.StringUtils;
|
|||||||
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.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.security.SignPDFWithCertRequest;
|
import stirling.software.SPDF.model.api.security.SignPDFWithCertRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.service.ServerCertificateServiceInterface;
|
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@@ -83,6 +81,7 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
@RequestMapping("/api/v1/security")
|
@RequestMapping("/api/v1/security")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Tag(name = "Security", description = "Security APIs")
|
@Tag(name = "Security", description = "Security APIs")
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class CertSignController {
|
public class CertSignController {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -102,15 +101,6 @@ public class CertSignController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
private final ServerCertificateServiceInterface serverCertificateService;
|
|
||||||
|
|
||||||
public CertSignController(
|
|
||||||
CustomPDFDocumentFactory pdfDocumentFactory,
|
|
||||||
@Autowired(required = false)
|
|
||||||
ServerCertificateServiceInterface serverCertificateService) {
|
|
||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
|
||||||
this.serverCertificateService = serverCertificateService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void sign(
|
private static void sign(
|
||||||
CustomPDFDocumentFactory pdfDocumentFactory,
|
CustomPDFDocumentFactory pdfDocumentFactory,
|
||||||
@@ -154,7 +144,6 @@ public class CertSignController {
|
|||||||
MediaType.APPLICATION_FORM_URLENCODED_VALUE
|
MediaType.APPLICATION_FORM_URLENCODED_VALUE
|
||||||
},
|
},
|
||||||
value = "/cert-sign")
|
value = "/cert-sign")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Sign PDF with a Digital Certificate",
|
summary = "Sign PDF with a Digital Certificate",
|
||||||
description =
|
description =
|
||||||
@@ -186,7 +175,6 @@ public class CertSignController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KeyStore ks = null;
|
KeyStore ks = null;
|
||||||
String keystorePassword = password;
|
|
||||||
|
|
||||||
switch (certType) {
|
switch (certType) {
|
||||||
case "PEM":
|
case "PEM":
|
||||||
@@ -205,24 +193,6 @@ public class CertSignController {
|
|||||||
ks = KeyStore.getInstance("JKS");
|
ks = KeyStore.getInstance("JKS");
|
||||||
ks.load(jksfile.getInputStream(), password.toCharArray());
|
ks.load(jksfile.getInputStream(), password.toCharArray());
|
||||||
break;
|
break;
|
||||||
case "SERVER":
|
|
||||||
if (serverCertificateService == null) {
|
|
||||||
throw ExceptionUtils.createIllegalArgumentException(
|
|
||||||
"error.serverCertificateNotAvailable",
|
|
||||||
"Server certificate service is not available in this edition");
|
|
||||||
}
|
|
||||||
if (!serverCertificateService.isEnabled()) {
|
|
||||||
throw ExceptionUtils.createIllegalArgumentException(
|
|
||||||
"error.serverCertificateDisabled",
|
|
||||||
"Server certificate feature is disabled");
|
|
||||||
}
|
|
||||||
if (!serverCertificateService.hasServerCertificate()) {
|
|
||||||
throw ExceptionUtils.createIllegalArgumentException(
|
|
||||||
"error.serverCertificateNotFound", "No server certificate configured");
|
|
||||||
}
|
|
||||||
ks = serverCertificateService.getServerKeyStore();
|
|
||||||
keystorePassword = serverCertificateService.getServerCertificatePassword();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw ExceptionUtils.createIllegalArgumentException(
|
throw ExceptionUtils.createIllegalArgumentException(
|
||||||
"error.invalidArgument",
|
"error.invalidArgument",
|
||||||
@@ -230,7 +200,7 @@ public class CertSignController {
|
|||||||
"certificate type: " + certType);
|
"certificate type: " + certType);
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateSignature createSignature = new CreateSignature(ks, keystorePassword.toCharArray());
|
CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
sign(
|
sign(
|
||||||
pdfDocumentFactory,
|
pdfDocumentFactory,
|
||||||
|
|||||||
+6
-4
@@ -46,6 +46,8 @@ import org.apache.xmpbox.xml.XmpSerializer;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@@ -53,20 +55,21 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
|
|||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.JsonDataResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.SecurityApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@SecurityApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/security")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Security", description = "Security APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GetInfoOnPDF {
|
public class GetInfoOnPDF {
|
||||||
|
|
||||||
@@ -186,7 +189,6 @@ public class GetInfoOnPDF {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/get-info-on-pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/get-info-on-pdf")
|
||||||
@JsonDataResponse
|
|
||||||
@Operation(summary = "Summary here", description = "desc. Input:PDF Output:JSON Type:SISO")
|
@Operation(summary = "Summary here", description = "desc. Input:PDF Output:JSON Type:SISO")
|
||||||
public ResponseEntity<byte[]> getPdfInfo(@ModelAttribute PDFFile request) throws IOException {
|
public ResponseEntity<byte[]> getPdfInfo(@ModelAttribute PDFFile request) throws IOException {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
|
|||||||
+6
-5
@@ -7,30 +7,32 @@ import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
|
|||||||
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
|
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.SPDF.model.api.security.AddPasswordRequest;
|
import stirling.software.SPDF.model.api.security.AddPasswordRequest;
|
||||||
import stirling.software.SPDF.model.api.security.PDFPasswordRequest;
|
import stirling.software.SPDF.model.api.security.PDFPasswordRequest;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.SecurityApi;
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@SecurityApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/security")
|
||||||
|
@Tag(name = "Security", description = "Security APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PasswordController {
|
public class PasswordController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-password")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-password")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Remove password from a PDF file",
|
summary = "Remove password from a PDF file",
|
||||||
description =
|
description =
|
||||||
@@ -57,7 +59,6 @@ public class PasswordController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-password")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/add-password")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Add password to a PDF file",
|
summary = "Add password to a PDF file",
|
||||||
description =
|
description =
|
||||||
|
|||||||
+7
-8
@@ -18,21 +18,22 @@ import org.springframework.http.ResponseEntity;
|
|||||||
import org.springframework.web.bind.WebDataBinder;
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
import org.springframework.web.bind.annotation.InitBinder;
|
import org.springframework.web.bind.annotation.InitBinder;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
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;
|
||||||
import stirling.software.SPDF.pdf.TextFinder;
|
import stirling.software.SPDF.pdf.TextFinder;
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.SecurityApi;
|
|
||||||
import stirling.software.common.model.api.security.RedactionArea;
|
import stirling.software.common.model.api.security.RedactionArea;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
@@ -40,8 +41,10 @@ import stirling.software.common.util.PdfUtils;
|
|||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
import stirling.software.common.util.propertyeditor.StringToArrayListPropertyEditor;
|
import stirling.software.common.util.propertyeditor.StringToArrayListPropertyEditor;
|
||||||
|
|
||||||
@SecurityApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/security")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Tag(name = "Security", description = "Security APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RedactController {
|
public class RedactController {
|
||||||
|
|
||||||
@@ -54,15 +57,13 @@ public class RedactController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/redact", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/redact", consumes = "multipart/form-data")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
operationId = "redactPdfManual",
|
|
||||||
summary = "Redacts areas and pages in a PDF document",
|
summary = "Redacts areas and pages in a PDF document",
|
||||||
description =
|
description =
|
||||||
"This operation takes an input PDF file with a list of areas, page"
|
"This operation takes an input PDF file with a list of areas, page"
|
||||||
+ " number(s)/range(s)/function(s) to redact. Input:PDF, Output:PDF,"
|
+ " number(s)/range(s)/function(s) to redact. Input:PDF, Output:PDF,"
|
||||||
+ " Type:SISO")
|
+ " Type:SISO")
|
||||||
public ResponseEntity<byte[]> redactPdfManual(@ModelAttribute ManualRedactPdfRequest request)
|
public ResponseEntity<byte[]> redactPDF(@ModelAttribute ManualRedactPdfRequest request)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
List<RedactionArea> redactionAreas = request.getRedactions();
|
List<RedactionArea> redactionAreas = request.getRedactions();
|
||||||
@@ -190,9 +191,7 @@ public class RedactController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(value = "/auto-redact", consumes = "multipart/form-data")
|
@AutoJobPostMapping(value = "/auto-redact", consumes = "multipart/form-data")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
operationId = "redactPdfAuto",
|
|
||||||
summary = "Redacts listOfText in a PDF document",
|
summary = "Redacts listOfText in a PDF document",
|
||||||
description =
|
description =
|
||||||
"This operation takes an input PDF file and redacts the provided listOfText."
|
"This operation takes an input PDF file and redacts the provided listOfText."
|
||||||
|
|||||||
+6
-4
@@ -9,28 +9,30 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||||
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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
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 lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import stirling.software.SPDF.config.swagger.StandardPdfResponse;
|
|
||||||
import stirling.software.common.annotations.AutoJobPostMapping;
|
import stirling.software.common.annotations.AutoJobPostMapping;
|
||||||
import stirling.software.common.annotations.api.SecurityApi;
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@SecurityApi
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/security")
|
||||||
|
@Tag(name = "Security", description = "Security APIs")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RemoveCertSignController {
|
public class RemoveCertSignController {
|
||||||
|
|
||||||
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
private final CustomPDFDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-cert-sign")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/remove-cert-sign")
|
||||||
@StandardPdfResponse
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Remove digital signature from PDF",
|
summary = "Remove digital signature from PDF",
|
||||||
description =
|
description =
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user