Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4082e3f96 | ||
|
|
c93a48b40d | ||
|
|
75e10efcbd |
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,5 @@
|
|||||||
blank_issues_enabled: true
|
blank_issues_enabled: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: 💬 Discord Server
|
- name: 💬 Discord Server
|
||||||
url: https://discord.gg/Cn8pWhQRxZ
|
url: https://discord.gg/HYmhKj45pU
|
||||||
about: You can join our Discord server for real time discussion and support
|
about: You can join our Discord server for real time discussion and support
|
||||||
|
|||||||
39
.github/labeler-config.yml
vendored
39
.github/labeler-config.yml
vendored
@@ -1,49 +1,20 @@
|
|||||||
Translation:
|
translation:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: 'src/main/resources/messages_*_*.properties'
|
- any-glob-to-any-file: 'src/main/resources/messages_*_*.properties'
|
||||||
- any-glob-to-any-file: 'scripts/ignore_translation.toml'
|
|
||||||
|
|
||||||
Front End:
|
Front End:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: 'src/main/resources/templates/**/*'
|
- any-glob-to-any-file: 'src/main/resources/templates/**'
|
||||||
- any-glob-to-any-file: 'src/main/resources/static/**/*'
|
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/**'
|
|
||||||
|
|
||||||
Java:
|
java:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: 'src/main/java/**/*.java'
|
- any-glob-to-any-file: 'src/main/java/**/*.java'
|
||||||
|
|
||||||
Back End:
|
documentation:
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*'
|
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/model/provider/**/*'
|
|
||||||
- any-glob-to-any-file: 'src/main/resources/settings.yml.template'
|
|
||||||
- any-glob-to-any-file: 'src/main/resources/banner.txt'
|
|
||||||
|
|
||||||
Security:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*'
|
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/model/provider/**/*'
|
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/model/AuthenticationType.java'
|
|
||||||
|
|
||||||
API:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/MetricsController.java'
|
|
||||||
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/**/*'
|
|
||||||
|
|
||||||
Documentation:
|
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: '**/*.md'
|
- any-glob-to-any-file: '**/*.md'
|
||||||
- any-glob-to-any-file: 'scripts/counter_translation.py'
|
|
||||||
- any-glob-to-any-file: 'scripts/ignore_translation.toml'
|
|
||||||
|
|
||||||
Docker:
|
docker:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: 'Dockerfile'
|
- any-glob-to-any-file: 'Dockerfile'
|
||||||
- any-glob-to-any-file: 'Dockerfile-*'
|
- any-glob-to-any-file: 'Dockerfile-*'
|
||||||
- any-glob-to-any-file: 'exampleYmlFiles/*.yml'
|
|
||||||
|
|
||||||
Test:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file: 'cucumber/**/*'
|
|
||||||
- any-glob-to-any-file: 'test*'
|
|
||||||
|
|||||||
93
.github/labels.yml
vendored
93
.github/labels.yml
vendored
@@ -1,93 +0,0 @@
|
|||||||
# Labels names are important as they are used by Release Drafter to decide
|
|
||||||
# regarding where to record them in changelog or if to skip them.
|
|
||||||
#
|
|
||||||
# The repository labels will be automatically configured using this file and
|
|
||||||
# the GitHub Action https://github.com/marketplace/actions/github-labeler.
|
|
||||||
- name: "Back End"
|
|
||||||
color: "20CE6C"
|
|
||||||
description: "Issues related to back-end development"
|
|
||||||
from_name: "Back end"
|
|
||||||
- name: "Bug"
|
|
||||||
description: "Something isn't working"
|
|
||||||
color: "EB9CA6"
|
|
||||||
from_name: "bug"
|
|
||||||
- name: "dependencies"
|
|
||||||
description: "Pull requests that update a dependency file"
|
|
||||||
color: "5AA8FC"
|
|
||||||
- name: "Docker"
|
|
||||||
description: "Pull requests that update Docker code"
|
|
||||||
color: "1FCEFF"
|
|
||||||
from_name: "docker"
|
|
||||||
- name: "Documentation"
|
|
||||||
description: "Improvements or additions to documentation"
|
|
||||||
color: "35ABFF"
|
|
||||||
from_name: "documentation"
|
|
||||||
- name: "Done for next release"
|
|
||||||
color: "0CDBD1"
|
|
||||||
- name: "Done"
|
|
||||||
color: "60F13B"
|
|
||||||
- name: "duplicate"
|
|
||||||
description: "This issue or pull request already exists"
|
|
||||||
color: "CDD1D5"
|
|
||||||
- name: "enhancement"
|
|
||||||
description: "New feature or request"
|
|
||||||
color: "A0EEEE"
|
|
||||||
- name: "fix needs confirmation"
|
|
||||||
color: "60A1E7"
|
|
||||||
description: "Fix needs to be confirmed"
|
|
||||||
- name: "Front End"
|
|
||||||
color: "BBD2F1"
|
|
||||||
description: "Issues related to front-end development"
|
|
||||||
- name: "github-actions"
|
|
||||||
description: "Pull requests that update GitHub Actions code"
|
|
||||||
color: "999999"
|
|
||||||
from_name: "github_actions"
|
|
||||||
- name: "good first issue"
|
|
||||||
description: "Good for newcomers"
|
|
||||||
color: "C1B8FF"
|
|
||||||
- name: "help wanted"
|
|
||||||
description: "Extra attention is needed"
|
|
||||||
color: "00E6C4"
|
|
||||||
- name: "invalid"
|
|
||||||
description: "This doesn't seem right"
|
|
||||||
color: "E5E566"
|
|
||||||
- name: "Java"
|
|
||||||
description: "Pull requests that update Java code"
|
|
||||||
color: "FF9E1F"
|
|
||||||
from_name: "java"
|
|
||||||
- name: "Long-term Enhancement"
|
|
||||||
color: "BFDEC3"
|
|
||||||
description: "Enhancements planned for the long term"
|
|
||||||
- name: "more-info-needed"
|
|
||||||
color: "00E4F8"
|
|
||||||
description: "More information is needed"
|
|
||||||
- name: "needs investigation"
|
|
||||||
color: "B8C3A7"
|
|
||||||
description: "Issues that require further investigation"
|
|
||||||
- name: "Prioritised enhancement"
|
|
||||||
color: "4BA2EE"
|
|
||||||
description: "High-priority enhancements"
|
|
||||||
- name: "question"
|
|
||||||
description: "Further information is requested"
|
|
||||||
color: "D97EE5"
|
|
||||||
- name: "Translation"
|
|
||||||
color: "9FABF9"
|
|
||||||
from_name: "translation"
|
|
||||||
- name: "upstream"
|
|
||||||
color: "DEDEDE"
|
|
||||||
- name: "v2"
|
|
||||||
color: "FFFF00"
|
|
||||||
- name: "wontfix"
|
|
||||||
description: "This will not be worked on"
|
|
||||||
color: "FFFFFF"
|
|
||||||
- name: "Security"
|
|
||||||
color: "000000"
|
|
||||||
description: "Security-related issues or pull requests"
|
|
||||||
- name: "API"
|
|
||||||
color: "FFFF00"
|
|
||||||
description: "API-related issues or pull requests"
|
|
||||||
- name: "Test"
|
|
||||||
color: "FF9E1F"
|
|
||||||
description: "Testing-related issues or pull requests"
|
|
||||||
- name: "Stale"
|
|
||||||
color: "000000"
|
|
||||||
1
.github/scripts/check_tabulator.py
vendored
1
.github/scripts/check_tabulator.py
vendored
@@ -1,5 +1,4 @@
|
|||||||
"""check_tabulator.py"""
|
"""check_tabulator.py"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|||||||
24
.github/workflows/manage-label.yml
vendored
24
.github/workflows/manage-label.yml
vendored
@@ -1,24 +0,0 @@
|
|||||||
name: Manage labels
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "30 20 * * *"
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
issues: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
labeler:
|
|
||||||
name: Labeler
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check out the repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Run Labeler
|
|
||||||
uses: crazy-max/ghaction-github-labeler@v5
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
yaml-file: .github/labels.yml
|
|
||||||
skip-delete: true
|
|
||||||
2
.github/workflows/sync_files.yml
vendored
2
.github/workflows/sync_files.yml
vendored
@@ -51,7 +51,6 @@ jobs:
|
|||||||
[1]: https://github.com/peter-evans/create-pull-request
|
[1]: https://github.com/peter-evans/create-pull-request
|
||||||
draft: false
|
draft: false
|
||||||
delete-branch: true
|
delete-branch: true
|
||||||
labels: github-actions
|
|
||||||
sync-readme:
|
sync-readme:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -89,4 +88,3 @@ jobs:
|
|||||||
[1]: https://github.com/peter-evans/create-pull-request
|
[1]: https://github.com/peter-evans/create-pull-request
|
||||||
draft: false
|
draft: false
|
||||||
delete-branch: true
|
delete-branch: true
|
||||||
labels: Documentation,Translation,github-actions
|
|
||||||
|
|||||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -29,8 +29,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Docker Compose
|
- name: Install Docker Compose
|
||||||
run: |
|
run: |
|
||||||
sudo curl -SL "https://github.com/docker/compose/releases/download/v2.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
sudo curl -SL "https://github.com/docker/compose/releases/download/v2.26.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
sudo chmod +x /usr/local/bin/docker-compose
|
# sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
|
|||||||
43
.gitignore
vendored
43
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
### Eclipse ###
|
### Eclipse ###
|
||||||
.metadata
|
.metadata
|
||||||
bin/
|
bin/
|
||||||
@@ -20,6 +22,7 @@ customFiles/
|
|||||||
configs/
|
configs/
|
||||||
watchedFolders/
|
watchedFolders/
|
||||||
|
|
||||||
|
|
||||||
# Gradle
|
# Gradle
|
||||||
.gradle
|
.gradle
|
||||||
.lock
|
.lock
|
||||||
@@ -116,28 +119,8 @@ watchedFolders/
|
|||||||
*.db
|
*.db
|
||||||
/build
|
/build
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
/.vscode
|
||||||
__pycache__/
|
/.idea
|
||||||
*.py[cod]
|
|
||||||
*.pyo
|
|
||||||
|
|
||||||
# Virtual environments
|
|
||||||
.env*
|
|
||||||
.venv*
|
|
||||||
env*/
|
|
||||||
venv*/
|
|
||||||
ENV/
|
|
||||||
env.bak/
|
|
||||||
venv.bak/
|
|
||||||
|
|
||||||
# VS Code
|
|
||||||
/.vscode/**/*
|
|
||||||
!/.vscode/settings.json
|
|
||||||
|
|
||||||
# IntelliJ IDEA
|
|
||||||
.idea/
|
|
||||||
*.iml
|
|
||||||
out/
|
|
||||||
|
|
||||||
# Ignore Mac DS_Store files
|
# Ignore Mac DS_Store files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
@@ -145,19 +128,3 @@ out/
|
|||||||
|
|
||||||
#cucumber
|
#cucumber
|
||||||
/cucumber/reports/**
|
/cucumber/reports/**
|
||||||
|
|
||||||
# Certs
|
|
||||||
*.p12
|
|
||||||
*.pem
|
|
||||||
*.crt
|
|
||||||
*.cer
|
|
||||||
*.der
|
|
||||||
*.key
|
|
||||||
*.csr
|
|
||||||
|
|
||||||
# cache
|
|
||||||
.ruff_cache
|
|
||||||
.mypy_cache
|
|
||||||
.pytest_cache
|
|
||||||
.ipynb_checkpoints
|
|
||||||
|
|
||||||
|
|||||||
53
.vscode/settings.json
vendored
53
.vscode/settings.json
vendored
@@ -1,53 +0,0 @@
|
|||||||
{
|
|
||||||
"java.compile.nullAnalysis.mode": "automatic",
|
|
||||||
"files.eol": "auto",
|
|
||||||
"java.configuration.updateBuildConfiguration": "interactive",
|
|
||||||
"black-formatter.args": ["--line-length", "127"],
|
|
||||||
"flake8.args": ["--max-line-length", "127"],
|
|
||||||
"pylint.args": ["max-line-length", "127"],
|
|
||||||
"[java]": {
|
|
||||||
"editor.tabSize": 4,
|
|
||||||
"editor.detectIndentation": false,
|
|
||||||
"editor.rulers": [127]
|
|
||||||
},
|
|
||||||
"[python]": {
|
|
||||||
"editor.tabSize": 2,
|
|
||||||
"editor.detectIndentation": false,
|
|
||||||
"editor.rulers": [127]
|
|
||||||
},
|
|
||||||
"[gradle-build]": {
|
|
||||||
"editor.tabSize": 4,
|
|
||||||
"editor.detectIndentation": false,
|
|
||||||
"editor.rulers": [127]
|
|
||||||
},
|
|
||||||
"[gradle]": {
|
|
||||||
"editor.tabSize": 4,
|
|
||||||
"editor.detectIndentation": false,
|
|
||||||
"editor.rulers": [127]
|
|
||||||
},
|
|
||||||
"[html]": {
|
|
||||||
"editor.tabSize": 2,
|
|
||||||
"editor.rulers": [127],
|
|
||||||
"files.trimFinalNewlines": false,
|
|
||||||
"files.insertFinalNewline": false
|
|
||||||
},
|
|
||||||
"[javascript]": {
|
|
||||||
"editor.tabSize": 2,
|
|
||||||
"editor.rulers": [127]
|
|
||||||
},
|
|
||||||
"[yaml]": {
|
|
||||||
"files.trimFinalNewlines": false,
|
|
||||||
"files.insertFinalNewline": false
|
|
||||||
},
|
|
||||||
"diffEditor.maxComputationTime": 0,
|
|
||||||
"editor.wordSegmenterLocales": null,
|
|
||||||
"editor.guides.bracketPairs": "active",
|
|
||||||
"editor.guides.bracketPairsHorizontal": "active",
|
|
||||||
"files.insertFinalNewline": true,
|
|
||||||
"files.trimFinalNewlines": true,
|
|
||||||
"files.trimTrailingWhitespace": true,
|
|
||||||
"editor.indentSize": "tabSize",
|
|
||||||
"editor.stickyScroll.enabled": false,
|
|
||||||
"editor.minimap.enabled": false,
|
|
||||||
"editor.formatOnSave": true
|
|
||||||
}
|
|
||||||
@@ -31,7 +31,7 @@ ENV DOCKER_ENABLE_SECURITY=false \
|
|||||||
PGID=1000 \
|
PGID=1000 \
|
||||||
UMASK=022 \
|
UMASK=022 \
|
||||||
FAT_DOCKER=true \
|
FAT_DOCKER=true \
|
||||||
INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false
|
INSTALL_BOOK_AND_ADVANCED_HTML_OPS=true
|
||||||
|
|
||||||
|
|
||||||
# JDK for app
|
# JDK for app
|
||||||
@@ -45,6 +45,7 @@ RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /et
|
|||||||
tini \
|
tini \
|
||||||
bash \
|
bash \
|
||||||
curl \
|
curl \
|
||||||
|
calibre@testing \
|
||||||
shadow \
|
shadow \
|
||||||
su-exec \
|
su-exec \
|
||||||
openssl \
|
openssl \
|
||||||
|
|||||||
56
README.md
56
README.md
@@ -2,7 +2,7 @@
|
|||||||
<h1 align="center">Stirling-PDF</h1>
|
<h1 align="center">Stirling-PDF</h1>
|
||||||
|
|
||||||
[](https://hub.docker.com/r/frooodle/s-pdf)
|
[](https://hub.docker.com/r/frooodle/s-pdf)
|
||||||
[](https://discord.gg/Cn8pWhQRxZ)
|
[](https://discord.gg/HYmhKj45pU)
|
||||||
[](https://github.com/Stirling-Tools/Stirling-PDF/)
|
[](https://github.com/Stirling-Tools/Stirling-PDF/)
|
||||||
[](https://github.com/Stirling-Tools/stirling-pdf)
|
[](https://github.com/Stirling-Tools/stirling-pdf)
|
||||||
[](https://www.paypal.com/donate/?hosted_button_id=MN7JPG5G6G3JL)
|
[](https://www.paypal.com/donate/?hosted_button_id=MN7JPG5G6G3JL)
|
||||||
@@ -165,46 +165,42 @@ Please view https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToUseOCR
|
|||||||
|
|
||||||
## Supported Languages
|
## Supported Languages
|
||||||
|
|
||||||
Stirling PDF currently supports 38!
|
Stirling PDF currently supports 32!
|
||||||
|
|
||||||
| Language | Progress |
|
| Language | Progress |
|
||||||
| ------------------------------------------- | -------------------------------------- |
|
| ------------------------------------------- | -------------------------------------- |
|
||||||
| Arabic (العربية) (ar_AR) |  |
|
|
||||||
| Basque (Euskara) (eu_ES) |  |
|
|
||||||
| Bulgarian (Български) (bg_BG) |  |
|
|
||||||
| Catalan (Català) (ca_CA) |  |
|
|
||||||
| Croatian (Hrvatski) (hr_HR) |  |
|
|
||||||
| Czech (Česky) (cs_CZ) |  |
|
|
||||||
| Danish (Dansk) (da_DK) |  |
|
|
||||||
| Dutch (Nederlands) (nl_NL) |  |
|
|
||||||
| English (English) (en_GB) |  |
|
| English (English) (en_GB) |  |
|
||||||
| English (US) (en_US) |  |
|
| English (US) (en_US) |  |
|
||||||
| French (Français) (fr_FR) |  |
|
| Arabic (العربية) (ar_AR) |  |
|
||||||
| German (Deutsch) (de_DE) |  |
|
| German (Deutsch) (de_DE) |  |
|
||||||
|
| French (Français) (fr_FR) |  |
|
||||||
|
| Spanish (Español) (es_ES) |  |
|
||||||
|
| Simplified Chinese (简体中文) (zh_CN) |  |
|
||||||
|
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||||
|
| Catalan (Català) (ca_CA) |  |
|
||||||
|
| Italian (Italiano) (it_IT) |  |
|
||||||
|
| Swedish (Svenska) (sv_SE) |  |
|
||||||
|
| Polish (Polski) (pl_PL) |  |
|
||||||
|
| Romanian (Română) (ro_RO) |  |
|
||||||
|
| Korean (한국어) (ko_KR) |  |
|
||||||
|
| Portuguese Brazilian (Português) (pt_BR) |  |
|
||||||
|
| Portuguese (Português) (pt_PT) |  |
|
||||||
|
| Russian (Русский) (ru_RU) |  |
|
||||||
|
| Basque (Euskara) (eu_ES) |  |
|
||||||
|
| Japanese (日本語) (ja_JP) |  |
|
||||||
|
| Dutch (Nederlands) (nl_NL) |  |
|
||||||
| Greek (Ελληνικά) (el_GR) |  |
|
| Greek (Ελληνικά) (el_GR) |  |
|
||||||
|
| Turkish (Türkçe) (tr_TR) |  |
|
||||||
|
| Indonesia (Bahasa Indonesia) (id_ID) |  |
|
||||||
| Hindi (हिंदी) (hi_IN) |  |
|
| Hindi (हिंदी) (hi_IN) |  |
|
||||||
| Hungarian (Magyar) (hu_HU) |  |
|
| Hungarian (Magyar) (hu_HU) |  |
|
||||||
| Indonesia (Bahasa Indonesia) (id_ID) |  |
|
| Bulgarian (Български) (bg_BG) |  |
|
||||||
| Irish (Gaeilge) (ga_IE) |  |
|
|
||||||
| Italian (Italiano) (it_IT) |  |
|
|
||||||
| Japanese (日本語) (ja_JP) |  |
|
|
||||||
| Korean (한국어) (ko_KR) |  |
|
|
||||||
| Norwegian (Norsk) (no_NB) |  |
|
|
||||||
| Polish (Polski) (pl_PL) |  |
|
|
||||||
| Portuguese (Português) (pt_PT) |  |
|
|
||||||
| Portuguese Brazilian (Português) (pt_BR) |  |
|
|
||||||
| Romanian (Română) (ro_RO) |  |
|
|
||||||
| Russian (Русский) (ru_RU) |  |
|
|
||||||
| Sebian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
| Sebian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
||||||
| Simplified Chinese (简体中文) (zh_CN) |  |
|
|
||||||
| Slovakian (Slovensky) (sk_SK) |  |
|
|
||||||
| Spanish (Español) (es_ES) |  |
|
|
||||||
| Swedish (Svenska) (sv_SE) |  |
|
|
||||||
| Thai (ไทย) (th_TH) |  |
|
|
||||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
|
||||||
| Turkish (Türkçe) (tr_TR) |  |
|
|
||||||
| Ukrainian (Українська) (uk_UA) |  |
|
| Ukrainian (Українська) (uk_UA) |  |
|
||||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
| Slovakian (Slovensky) (sk_SK) |  |
|
||||||
|
| Czech (Česky) (cs_CZ) |  |
|
||||||
|
| Croatian (Hrvatski) (hr_HR) |  |
|
||||||
|
| Norwegian (Norsk) (no_NB) |  |
|
||||||
|
|
||||||
## Contributing (creating issues, translations, fixing bugs, etc.)
|
## Contributing (creating issues, translations, fixing bugs, etc.)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
id "org.springframework.boot" version "3.3.0"
|
id "org.springframework.boot" version "3.3.0"
|
||||||
id "io.spring.dependency-management" version "1.1.6"
|
id "io.spring.dependency-management" version "1.1.5"
|
||||||
id "org.springdoc.openapi-gradle-plugin" version "1.8.0"
|
id "org.springdoc.openapi-gradle-plugin" version "1.8.0"
|
||||||
id "io.swagger.swaggerhub" version "1.3.2"
|
id "io.swagger.swaggerhub" version "1.3.2"
|
||||||
id "edu.sc.seis.launch4j" version "3.0.5"
|
id "edu.sc.seis.launch4j" version "3.0.5"
|
||||||
@@ -12,11 +12,11 @@ plugins {
|
|||||||
import com.github.jk1.license.render.*
|
import com.github.jk1.license.render.*
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
springBootVersion = "3.3.2"
|
springBootVersion = "3.3.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "stirling.software"
|
group = "stirling.software"
|
||||||
version = "0.26.2"
|
version = "0.26.1"
|
||||||
|
|
||||||
// 17 is lowest but we support and recommend 21
|
// 17 is lowest but we support and recommend 21
|
||||||
sourceCompatibility = "17"
|
sourceCompatibility = "17"
|
||||||
@@ -40,7 +40,6 @@ sourceSets {
|
|||||||
exclude "stirling/software/SPDF/controller/web/AccountWebController.java"
|
exclude "stirling/software/SPDF/controller/web/AccountWebController.java"
|
||||||
exclude "stirling/software/SPDF/controller/web/DatabaseWebController.java"
|
exclude "stirling/software/SPDF/controller/web/DatabaseWebController.java"
|
||||||
exclude "stirling/software/SPDF/model/ApiKeyAuthenticationToken.java"
|
exclude "stirling/software/SPDF/model/ApiKeyAuthenticationToken.java"
|
||||||
exclude "stirling/software/SPDF/model/AttemptCounter.java"
|
|
||||||
exclude "stirling/software/SPDF/model/Authority.java"
|
exclude "stirling/software/SPDF/model/Authority.java"
|
||||||
exclude "stirling/software/SPDF/model/PersistentLogin.java"
|
exclude "stirling/software/SPDF/model/PersistentLogin.java"
|
||||||
exclude "stirling/software/SPDF/model/User.java"
|
exclude "stirling/software/SPDF/model/User.java"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
appVersion: 0.26.2
|
appVersion: 0.26.1
|
||||||
description: locally hosted web application that allows you to perform various operations
|
description: locally hosted web application that allows you to perform various operations
|
||||||
on PDF files
|
on PDF files
|
||||||
home: https://github.com/Stirling-Tools/Stirling-PDF
|
home: https://github.com/Stirling-Tools/Stirling-PDF
|
||||||
|
|||||||
@@ -62,10 +62,8 @@ spec:
|
|||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
securityContext:
|
securityContext:
|
||||||
{{- toYaml .Values.containerSecurityContext | nindent 10 }}
|
{{- toYaml .Values.containerSecurityContext | nindent 10 }}
|
||||||
env:
|
|
||||||
- name: SYSTEM_ROOTURIPATH
|
|
||||||
value: {{ .Values.rootPath}}
|
|
||||||
{{- if .Values.envs }}
|
{{- if .Values.envs }}
|
||||||
|
env:
|
||||||
{{ toYaml .Values.envs | indent 8 }}
|
{{ toYaml .Values.envs | indent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if .Values.extraArgs }}
|
{{- if .Values.extraArgs }}
|
||||||
@@ -77,13 +75,13 @@ spec:
|
|||||||
containerPort: 8080
|
containerPort: 8080
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: {{ .Values.rootPath}}
|
path: /
|
||||||
port: http
|
port: http
|
||||||
{{ toYaml .Values.probes.livenessHttpGetConfig | indent 12 }}
|
{{ toYaml .Values.probes.livenessHttpGetConfig | indent 12 }}
|
||||||
{{ toYaml .Values.probes.liveness | indent 10 }}
|
{{ toYaml .Values.probes.liveness | indent 10 }}
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: {{ .Values.rootPath}}
|
path: /
|
||||||
port: http
|
port: http
|
||||||
{{ toYaml .Values.probes.readinessHttpGetConfig | indent 12 }}
|
{{ toYaml .Values.probes.readinessHttpGetConfig | indent 12 }}
|
||||||
{{ toYaml .Values.probes.readiness | indent 10 }}
|
{{ toYaml .Values.probes.readiness | indent 10 }}
|
||||||
|
|||||||
@@ -15,9 +15,6 @@ secret:
|
|||||||
commonLabels: {}
|
commonLabels: {}
|
||||||
# team_name: dev
|
# team_name: dev
|
||||||
|
|
||||||
# rootpath for the application
|
|
||||||
rootPath: /
|
|
||||||
|
|
||||||
envs: []
|
envs: []
|
||||||
# - name: UI_APP_NAME
|
# - name: UI_APP_NAME
|
||||||
# value: "Stirling PDF"
|
# value: "Stirling PDF"
|
||||||
@@ -27,6 +24,8 @@ envs: []
|
|||||||
# value: "Stirling PDF"
|
# value: "Stirling PDF"
|
||||||
# - name: ALLOW_GOOGLE_VISIBILITY
|
# - name: ALLOW_GOOGLE_VISIBILITY
|
||||||
# value: "true"
|
# value: "true"
|
||||||
|
# - name: APP_ROOT_PATH
|
||||||
|
# value: "/"
|
||||||
# - name: APP_LOCALE
|
# - name: APP_LOCALE
|
||||||
# value: "en_GB"
|
# value: "en_GB"
|
||||||
|
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
%PDF-1.3
|
|
||||||
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
|
|
||||||
1 0 obj
|
|
||||||
<<
|
|
||||||
/F1 2 0 R
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
2 0 obj
|
|
||||||
<<
|
|
||||||
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
3 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 9 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
4 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 10 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
5 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 11 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
6 0 obj
|
|
||||||
<<
|
|
||||||
/PageMode /UseNone /Pages 8 0 R /Type /Catalog
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
7 0 obj
|
|
||||||
<<
|
|
||||||
/Author (anonymous) /CreationDate (D:20240718233034+00'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20240718233034+00'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
|
||||||
/Subject (unspecified) /Title (untitled) /Trapped /False
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
8 0 obj
|
|
||||||
<<
|
|
||||||
/Count 3 /Kids [ 3 0 R 4 0 R 5 0 R ] /Type /Pages
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
9 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 210
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@Gb79+X'F"5[`EfJOD4:mD<%*=m+N>oDG,>NK`<U'B^0WYY,dWl^i_UcRk`<"L=<NPC$BtQ<5l$3<Y!?BuoCSYQ6GSt25lpqr0IrP?S[b)9%M"e'HHFqcRO'9eRaR0'DYi*Y.:nEMFAoTM;rPL%EF]`CfoELVl_Q,"LS:%iI;Nc[&bG.*65O]ecfK1'*<>5P_s[usI/ph*0pV~>endstream
|
|
||||||
endobj
|
|
||||||
10 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 209
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@Gb79+X'F"5Y`EfJOV2A9=!fB]F'tK1LS`,]G+MiTenb&V2-^hqa(5IE#Nr59/!"Qm*5_(BdF!0&h!Yhk/A+\iS'%6tuO$O)9LaZS+flr([1p2&#RS1p/gT[B;rDj-=&=iqUlj(P^/5U@eCFqn4:<lU`l`.HXqG-',hJH.DI.(6L\luSAW`Q'oje[qgVLVIXg%PXe+,<$7('~>endstream
|
|
||||||
endobj
|
|
||||||
11 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 209
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@GbmK%f(e+0_`ODoa2.):e/i+N3r(.o*Qf\gSNb(bt4FIubi@GIOE=p8Ir3;CbQ@KuG^cdJhODZKQ*upt+*rdZ%!mFmN$*.P)K;`s#]G=8AO3s3DGB.RCOn?[F]bEIg,a>25?B%dh\Z/C6opFE'el@I,P\u\V\]:*JYrrsNJ&d,11VL;$h!43eGu&1X6$+5-h\Vr6!+>4Je,~>endstream
|
|
||||||
endobj
|
|
||||||
xref
|
|
||||||
0 12
|
|
||||||
0000000000 65535 f
|
|
||||||
0000000073 00000 n
|
|
||||||
0000000104 00000 n
|
|
||||||
0000000211 00000 n
|
|
||||||
0000000404 00000 n
|
|
||||||
0000000598 00000 n
|
|
||||||
0000000792 00000 n
|
|
||||||
0000000860 00000 n
|
|
||||||
0000001156 00000 n
|
|
||||||
0000001227 00000 n
|
|
||||||
0000001527 00000 n
|
|
||||||
0000001827 00000 n
|
|
||||||
trailer
|
|
||||||
<<
|
|
||||||
/ID
|
|
||||||
[<0d5cf047e754e05f8d574f067785875c><0d5cf047e754e05f8d574f067785875c>]
|
|
||||||
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
|
||||||
|
|
||||||
/Info 7 0 R
|
|
||||||
/Root 6 0 R
|
|
||||||
/Size 12
|
|
||||||
>>
|
|
||||||
startxref
|
|
||||||
2127
|
|
||||||
%%EOF
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
%PDF-1.3
|
|
||||||
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
|
|
||||||
1 0 obj
|
|
||||||
<<
|
|
||||||
/F1 2 0 R
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
2 0 obj
|
|
||||||
<<
|
|
||||||
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
3 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 9 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
4 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 10 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
5 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 11 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
6 0 obj
|
|
||||||
<<
|
|
||||||
/PageMode /UseNone /Pages 8 0 R /Type /Catalog
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
7 0 obj
|
|
||||||
<<
|
|
||||||
/Author (anonymous) /CreationDate (D:20240718233034+00'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20240718233034+00'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
|
||||||
/Subject (unspecified) /Title (untitled) /Trapped /False
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
8 0 obj
|
|
||||||
<<
|
|
||||||
/Count 3 /Kids [ 3 0 R 4 0 R 5 0 R ] /Type /Pages
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
9 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 207
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@G:CDb.*/<p2MVk["e@)7*Z0@"b%+@f/9pA%_U<oOkVp?PnGRb81iPg?0i?(]%^_CSf##%;<!7Ne/-%RR^p@t7hKYZ9eJVHV]fjjHIB:6DrW+2\p16@*`r^CpQZZH'2Pjqd<.&hM2UO%$Wi$te%4QmS;<E"QS\!deQG_XtuEK>b(UbS>%`/0S`k\\5'TNY0mmgH?`8]i_0~>endstream
|
|
||||||
endobj
|
|
||||||
10 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 207
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@G]afWJ'Lm;=if<;s>V*7BTJ]oQ@P!(q5S+WG1%>L@?8Ue;c>[fY&&IOd5@t@TY@+q.5T<Z'81"J("KhsBa+&u4"n'#6)AjfImh)%$0tVC:aGk",=aJJH#/4]i.WJr9c"cibYm:M-44<%FFlG0Cl\Z'nmo7C"TR+7dk3T#iD(9Pq'\;rQku%o>A_`50SO&7M04=8M'O<Am~>endstream
|
|
||||||
endobj
|
|
||||||
11 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 209
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@GYmu@>'Ld5[if35r/JNaJ.A.7fP9RpSN*8k^-sEER0,enq1Rsuo@R/uCO-^&Y`F'9d^a?9)?ns+F&dXm[HMgPn6Ep+%TRk5Nh+!(+[H#H:U^.^(YL,PKS'%j/:3O\hJVEK-UUekJTd[A$N^((K^#0Du`i@,/^f5KiUISGr")3/+f9NF8NO1+iUgm^b"X\cE^+[:s!0]Gu6i~>endstream
|
|
||||||
endobj
|
|
||||||
xref
|
|
||||||
0 12
|
|
||||||
0000000000 65535 f
|
|
||||||
0000000073 00000 n
|
|
||||||
0000000104 00000 n
|
|
||||||
0000000211 00000 n
|
|
||||||
0000000404 00000 n
|
|
||||||
0000000598 00000 n
|
|
||||||
0000000792 00000 n
|
|
||||||
0000000860 00000 n
|
|
||||||
0000001156 00000 n
|
|
||||||
0000001227 00000 n
|
|
||||||
0000001524 00000 n
|
|
||||||
0000001822 00000 n
|
|
||||||
trailer
|
|
||||||
<<
|
|
||||||
/ID
|
|
||||||
[<407fc55425168745e56176202aad30c9><407fc55425168745e56176202aad30c9>]
|
|
||||||
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
|
||||||
|
|
||||||
/Info 7 0 R
|
|
||||||
/Root 6 0 R
|
|
||||||
/Size 12
|
|
||||||
>>
|
|
||||||
startxref
|
|
||||||
2122
|
|
||||||
%%EOF
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
%PDF-1.3
|
|
||||||
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
|
|
||||||
1 0 obj
|
|
||||||
<<
|
|
||||||
/F1 2 0 R
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
2 0 obj
|
|
||||||
<<
|
|
||||||
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
3 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 9 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
4 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 10 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
5 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 11 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
6 0 obj
|
|
||||||
<<
|
|
||||||
/PageMode /UseNone /Pages 8 0 R /Type /Catalog
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
7 0 obj
|
|
||||||
<<
|
|
||||||
/Author (anonymous) /CreationDate (D:20240718233034+00'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20240718233034+00'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
|
||||||
/Subject (unspecified) /Title (untitled) /Trapped /False
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
8 0 obj
|
|
||||||
<<
|
|
||||||
/Count 3 /Kids [ 3 0 R 4 0 R 5 0 R ] /Type /Pages
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
9 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 209
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@G]+0EH(e/_@iZH]:>:>hu1e>07BJg5<'#:.C1n)e#(QJ6R1Rsuo_gpn.+0-H5$/#"iYR[B.9\'>7!aDAC*rf/t&6O#aH<?-7IT'\?X(&TcABG=ON*Nq`4k=o&p@3,0*31r<)TAP2Pk94p0\"R-_sY1$AYo[8B\?4R>feLAB\mpjZhp"`@J3;"Fm97#9+W,"eb95\+#p\^HN~>endstream
|
|
||||||
endobj
|
|
||||||
10 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 209
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@G]+0EX'Eriuig+>QHNeD'#n%Sq#n%BW`C'uDUOYK)HdS4E9JMsp+HUmDj&H-t*4?UamXX0peVspk"i_@ba+&u"J>UYDKV_^G,7V==aTZZ<YO7:sNSQ[6"Ja-29NtYjd#=`J@D'h+[QW=:EEb?A<k!f+\`g^?,Vgp7_)91[lR\f.Tkf7VIPLVYM&deF!aYt9Ip^"N",3F'*W~>endstream
|
|
||||||
endobj
|
|
||||||
11 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 209
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@G]+0EH(e/_@iZH]:>J`g!jPCLm;?AgU"fdk"PQZD\d?lRI_oWc[$tp^]O\:3fK8kWeX2&Jcg0+RoJ]j;2j*upu!b4.o&f)b$I@7CfIYjP^#\VjhC=QhQ]^lV-@<0Tam!0.+Dn@("AK%N,Uc7hb+6VoQ$q2q[7]BB92RoY/.j2N028i1jNf'@<1+Fqf$1&"8omHk`#DHP>OT~>endstream
|
|
||||||
endobj
|
|
||||||
xref
|
|
||||||
0 12
|
|
||||||
0000000000 65535 f
|
|
||||||
0000000073 00000 n
|
|
||||||
0000000104 00000 n
|
|
||||||
0000000211 00000 n
|
|
||||||
0000000404 00000 n
|
|
||||||
0000000598 00000 n
|
|
||||||
0000000792 00000 n
|
|
||||||
0000000860 00000 n
|
|
||||||
0000001156 00000 n
|
|
||||||
0000001227 00000 n
|
|
||||||
0000001526 00000 n
|
|
||||||
0000001826 00000 n
|
|
||||||
trailer
|
|
||||||
<<
|
|
||||||
/ID
|
|
||||||
[<80da26147a484f2b7573da8151a93d2e><80da26147a484f2b7573da8151a93d2e>]
|
|
||||||
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
|
||||||
|
|
||||||
/Info 7 0 R
|
|
||||||
/Root 6 0 R
|
|
||||||
/Size 12
|
|
||||||
>>
|
|
||||||
startxref
|
|
||||||
2126
|
|
||||||
%%EOF
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,106 +0,0 @@
|
|||||||
%PDF-1.3
|
|
||||||
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
|
|
||||||
1 0 obj
|
|
||||||
<<
|
|
||||||
/F1 2 0 R
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
2 0 obj
|
|
||||||
<<
|
|
||||||
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
3 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 9 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
4 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 10 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
5 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 11 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
6 0 obj
|
|
||||||
<<
|
|
||||||
/PageMode /UseNone /Pages 8 0 R /Type /Catalog
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
7 0 obj
|
|
||||||
<<
|
|
||||||
/Author (anonymous) /CreationDate (D:20240718233034+00'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20240718233034+00'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
|
||||||
/Subject (unspecified) /Title (untitled) /Trapped /False
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
8 0 obj
|
|
||||||
<<
|
|
||||||
/Count 3 /Kids [ 3 0 R 4 0 R 5 0 R ] /Type /Pages
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
9 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 206
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@G\IO3f&4Lr[@S4&T2aReWZ3N'9",Ncra>5AuK^J(o@r?=EP>b]h[L@XZ8q7#[c:#H2:^/=b,p3^,&f-Q.'H%!U?%N\iVa1pLMlh/41\A8@dF5@0al:-1?L;D%LpL3g\9`.3c6N/Mp=sE/nO%^@%Cc3`]e`qqS@[pkUWemMZC<P\fkqa55u)*hIUoU437-gb!e_*&B/,&~>endstream
|
|
||||||
endobj
|
|
||||||
10 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 209
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@G\IO3V'LdA_ig"8P1PS=kA5Q_GQ\P]*S3\>Q`jHYt?8UdkV`6]UV*On)+1VMV+A@.iF:*6sWfM9f"s.NmVuMto!p7-+,Rb<.h,pdi-&OQ5KO\RRFj.j"A)ScTQ7$hudF^TnZ'XuQA5"O]rYkt><-DJmj'"Ri>n!4`^m409XX`e)AR'*rGsn6m79.18+^ba=qRuss"-A3k+9~>endstream
|
|
||||||
endobj
|
|
||||||
11 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 210
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@G]+0EH(e/_@iZH]:.1fBHK`Xl'[i1&AjX(\k8hbgo(QJ6R1Rsuo6_I1A5Gg$JL;D#$J2CX;+Cf*cUHk2%H1XmpWe+qZ5moJ#B]>b%%[d,mfSSkS4A:Q4NlOFfrL7eA,s45"eUSakM;927AA,1"-LZ)&nZ/ah=8_X7:?ZMj@J@;r7d`t]Z0\d39M%:$k8[S5D"2oSap4s80l?~>endstream
|
|
||||||
endobj
|
|
||||||
xref
|
|
||||||
0 12
|
|
||||||
0000000000 65535 f
|
|
||||||
0000000073 00000 n
|
|
||||||
0000000104 00000 n
|
|
||||||
0000000211 00000 n
|
|
||||||
0000000404 00000 n
|
|
||||||
0000000598 00000 n
|
|
||||||
0000000792 00000 n
|
|
||||||
0000000860 00000 n
|
|
||||||
0000001156 00000 n
|
|
||||||
0000001227 00000 n
|
|
||||||
0000001523 00000 n
|
|
||||||
0000001823 00000 n
|
|
||||||
trailer
|
|
||||||
<<
|
|
||||||
/ID
|
|
||||||
[<88edee24ee67bd7d6b7cf53cfa2222b0><88edee24ee67bd7d6b7cf53cfa2222b0>]
|
|
||||||
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
|
||||||
|
|
||||||
/Info 7 0 R
|
|
||||||
/Root 6 0 R
|
|
||||||
/Size 12
|
|
||||||
>>
|
|
||||||
startxref
|
|
||||||
2124
|
|
||||||
%%EOF
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
%PDF-1.3
|
|
||||||
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
|
|
||||||
1 0 obj
|
|
||||||
<<
|
|
||||||
/F1 2 0 R
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
2 0 obj
|
|
||||||
<<
|
|
||||||
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
3 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 9 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
4 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 10 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
5 0 obj
|
|
||||||
<<
|
|
||||||
/Contents 11 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
|
|
||||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
|
||||||
>> /Rotate 0 /Trans <<
|
|
||||||
|
|
||||||
>>
|
|
||||||
/Type /Page
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
6 0 obj
|
|
||||||
<<
|
|
||||||
/PageMode /UseNone /Pages 8 0 R /Type /Catalog
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
7 0 obj
|
|
||||||
<<
|
|
||||||
/Author (anonymous) /CreationDate (D:20240718233034+00'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20240718233034+00'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
|
||||||
/Subject (unspecified) /Title (untitled) /Trapped /False
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
8 0 obj
|
|
||||||
<<
|
|
||||||
/Count 3 /Kids [ 3 0 R 4 0 R 5 0 R ] /Type /Pages
|
|
||||||
>>
|
|
||||||
endobj
|
|
||||||
9 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 209
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@GYmu@>'Ld5[if35rI0]sG)F[U^"c>T)"\\os-r:1V0,enq1Rsuo,*67.@k7U.LRF-P.e"CM2V!>iYi<g`nXh!K?n@$t^rY1$+^0'>=B8H6e;F1WmG#,(eS00(Qe9&:O@nI879DTsT,njXAB?`8:>,Hn3*RV!qh4;&@6%]<9Y*>QZ].Z5o;RAZXg7d[#+bphHs_Ep!QR2TZ2~>endstream
|
|
||||||
endobj
|
|
||||||
10 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 210
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@G]+0EH(e/_@iZH]:>=,iY1bE)XN?M;1'J/>i&HY;gks]*rj:!DKpb8@`prC#N+9E#o#-<G*!#p7e6j-1sX2k5S,6XmM"taYkfK^k">%usEeEk=sR<UT"dm`rXD;!S`_jS9LU+(R%e'V%WSMfHP.pXZEQqTQq=&D[I[PS(41(NIAZ1R/U?:Z=hSXu!NDF)bpG2F+/I/q/u1-Y~>endstream
|
|
||||||
endobj
|
|
||||||
11 0 obj
|
|
||||||
<<
|
|
||||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 209
|
|
||||||
>>
|
|
||||||
stream
|
|
||||||
Gap@G_$YcZ'LhbF`EQB$nqi=8S<;#HbK3&f>rnodRPo`Vf4P[3cJidY(I=[K5NWCT'<lHgci?oCRVNST&[k#q4oSC0FWgAt1pD4d_(hIRjn_Nt+cFgJlfm[1U8@/M4r^Pk<@F!@e?%/!-Vq;]nfdLi9]P2M)ck9?)%oNXa_\N<-d"(pjlH%-G`T@Sj&P(j6.@#Xh\Vr6!1iI2/H~>endstream
|
|
||||||
endobj
|
|
||||||
xref
|
|
||||||
0 12
|
|
||||||
0000000000 65535 f
|
|
||||||
0000000073 00000 n
|
|
||||||
0000000104 00000 n
|
|
||||||
0000000211 00000 n
|
|
||||||
0000000404 00000 n
|
|
||||||
0000000598 00000 n
|
|
||||||
0000000792 00000 n
|
|
||||||
0000000860 00000 n
|
|
||||||
0000001156 00000 n
|
|
||||||
0000001227 00000 n
|
|
||||||
0000001526 00000 n
|
|
||||||
0000001827 00000 n
|
|
||||||
trailer
|
|
||||||
<<
|
|
||||||
/ID
|
|
||||||
[<4fcc82a085fe71e34a32d1b23c8b939f><4fcc82a085fe71e34a32d1b23c8b939f>]
|
|
||||||
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
|
||||||
|
|
||||||
/Info 7 0 R
|
|
||||||
/Root 6 0 R
|
|
||||||
/Size 12
|
|
||||||
>>
|
|
||||||
startxref
|
|
||||||
2127
|
|
||||||
%%EOF
|
|
||||||
@@ -14,8 +14,3 @@ def after_scenario(context, scenario):
|
|||||||
os.remove('response_file')
|
os.remove('response_file')
|
||||||
if hasattr(context, 'file_name') and os.path.exists(context.file_name):
|
if hasattr(context, 'file_name') and os.path.exists(context.file_name):
|
||||||
os.remove(context.file_name)
|
os.remove(context.file_name)
|
||||||
|
|
||||||
# Remove any temporary files
|
|
||||||
for temp_file in os.listdir('.'):
|
|
||||||
if temp_file.startswith('genericNonCustomisableName') or temp_file.startswith('temp_image_'):
|
|
||||||
os.remove(temp_file)
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
@example @general
|
@example
|
||||||
Feature: API Validation
|
Feature: API Validation
|
||||||
|
|
||||||
@positive @password
|
@positive @password
|
||||||
@@ -92,10 +92,10 @@ Feature: API Validation
|
|||||||
| threshold | 90 |
|
| threshold | 90 |
|
||||||
| whitePercent | 99.9 |
|
| whitePercent | 99.9 |
|
||||||
When I send the API request to the endpoint "/api/v1/misc/remove-blanks"
|
When I send the API request to the endpoint "/api/v1/misc/remove-blanks"
|
||||||
Then the response content type should be "application/octet-stream"
|
Then the response content type should be "application/pdf"
|
||||||
And the response file should have extension ".zip"
|
|
||||||
And the response ZIP should contain 2 files
|
|
||||||
And the response file should have size greater than 0
|
And the response file should have size greater than 0
|
||||||
|
And the response PDF should contain 0 pages
|
||||||
|
And the response status code should be 200
|
||||||
|
|
||||||
@positive @flatten
|
@positive @flatten
|
||||||
Scenario: Flatten PDF
|
Scenario: Flatten PDF
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Feature: API Validation
|
|||||||
@ocr @positive
|
@ocr @positive
|
||||||
Scenario: Extract Image Scans
|
Scenario: Extract Image Scans
|
||||||
Given I generate a PDF file as "fileInput"
|
Given I generate a PDF file as "fileInput"
|
||||||
And the pdf contains 3 images of size 300x300 on 2 pages
|
And the pdf contains 3 images on 2 pages
|
||||||
And the request data includes
|
And the request data includes
|
||||||
| parameter | value |
|
| parameter | value |
|
||||||
| angleThreshold | 5 |
|
| angleThreshold | 5 |
|
||||||
@@ -125,7 +125,8 @@ Feature: API Validation
|
|||||||
|
|
||||||
@ocr
|
@ocr
|
||||||
Scenario: PDFA
|
Scenario: PDFA
|
||||||
Given I use an example file at "exampleFiles/pdfa2.pdf" as parameter "fileInput"
|
Given I generate a PDF file as "fileInput"
|
||||||
|
And the pdf contains 3 pages with random text
|
||||||
And the request data includes
|
And the request data includes
|
||||||
| parameter | value |
|
| parameter | value |
|
||||||
| outputFormat | pdfa |
|
| outputFormat | pdfa |
|
||||||
@@ -136,7 +137,8 @@ Feature: API Validation
|
|||||||
|
|
||||||
@ocr
|
@ocr
|
||||||
Scenario: PDFA1
|
Scenario: PDFA1
|
||||||
Given I use an example file at "exampleFiles/pdfa1.pdf" as parameter "fileInput"
|
Given I generate a PDF file as "fileInput"
|
||||||
|
And the pdf contains 3 pages with random text
|
||||||
And the request data includes
|
And the request data includes
|
||||||
| parameter | value |
|
| parameter | value |
|
||||||
| outputFormat | pdfa-1 |
|
| outputFormat | pdfa-1 |
|
||||||
@@ -147,7 +149,8 @@ Feature: API Validation
|
|||||||
|
|
||||||
@compress @ghostscript @positive
|
@compress @ghostscript @positive
|
||||||
Scenario: Compress
|
Scenario: Compress
|
||||||
Given I use an example file at "exampleFiles/ghost3.pdf" as parameter "fileInput"
|
Given I generate a PDF file as "fileInput"
|
||||||
|
And the pdf contains 3 pages with random text
|
||||||
And the request data includes
|
And the request data includes
|
||||||
| parameter | value |
|
| parameter | value |
|
||||||
| optimizeLevel | 4 |
|
| optimizeLevel | 4 |
|
||||||
@@ -158,7 +161,8 @@ Feature: API Validation
|
|||||||
|
|
||||||
@compress @ghostscript @positive
|
@compress @ghostscript @positive
|
||||||
Scenario: Compress
|
Scenario: Compress
|
||||||
Given I use an example file at "exampleFiles/ghost2.pdf" as parameter "fileInput"
|
Given I generate a PDF file as "fileInput"
|
||||||
|
And the pdf contains 3 pages with random text
|
||||||
And the request data includes
|
And the request data includes
|
||||||
| parameter | value |
|
| parameter | value |
|
||||||
| optimizeLevel | 1 |
|
| optimizeLevel | 1 |
|
||||||
@@ -171,7 +175,8 @@ Feature: API Validation
|
|||||||
|
|
||||||
@compress @ghostscript @positive
|
@compress @ghostscript @positive
|
||||||
Scenario: Compress
|
Scenario: Compress
|
||||||
Given I use an example file at "exampleFiles/ghost1.pdf" as parameter "fileInput"
|
Given I generate a PDF file as "fileInput"
|
||||||
|
And the pdf contains 3 pages with random text
|
||||||
And the request data includes
|
And the request data includes
|
||||||
| parameter | value |
|
| parameter | value |
|
||||||
| optimizeLevel | 1 |
|
| optimizeLevel | 1 |
|
||||||
|
|||||||
@@ -94,23 +94,3 @@ Feature: API Validation
|
|||||||
| 1 | 10 | 2 | 10 |
|
| 1 | 10 | 2 | 10 |
|
||||||
|
|
||||||
|
|
||||||
@extract-images
|
|
||||||
Scenario Outline: Extract Image Scans
|
|
||||||
Given I use an example file at "exampleFiles/images.pdf" as parameter "fileInput"
|
|
||||||
And the request data includes
|
|
||||||
| parameter | value |
|
|
||||||
| format | <format> |
|
|
||||||
When I send the API request to the endpoint "/api/v1/misc/extract-images"
|
|
||||||
Then the response content type should be "application/octet-stream"
|
|
||||||
And the response file should have extension ".zip"
|
|
||||||
And the response ZIP should contain 20 files
|
|
||||||
And the response file should have size greater than 0
|
|
||||||
And the response status code should be 200
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
| format |
|
|
||||||
| png |
|
|
||||||
| gif |
|
|
||||||
| jpeg |
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,11 @@ import io
|
|||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
from reportlab.lib.pagesizes import letter
|
from reportlab.lib.pagesizes import letter
|
||||||
from reportlab.lib.utils import ImageReader
|
|
||||||
from reportlab.pdfgen import canvas
|
from reportlab.pdfgen import canvas
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import requests
|
import requests
|
||||||
import zipfile
|
import zipfile
|
||||||
import shutil
|
import shutil
|
||||||
import re
|
|
||||||
from PIL import Image, ImageDraw
|
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# GIVEN #
|
# GIVEN #
|
||||||
@@ -46,6 +43,8 @@ def step_use_example_file(context, filePath, fileInput):
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
raise FileNotFoundError(f"The example file '{filePath}' does not exist.")
|
raise FileNotFoundError(f"The example file '{filePath}' does not exist.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@given('the pdf contains {page_count:d} pages')
|
@given('the pdf contains {page_count:d} pages')
|
||||||
def step_pdf_contains_pages(context, page_count):
|
def step_pdf_contains_pages(context, page_count):
|
||||||
writer = PdfWriter()
|
writer = PdfWriter()
|
||||||
@@ -67,6 +66,8 @@ def step_pdf_contains_blank_pages(context, page_count):
|
|||||||
context.files[context.param_name].close()
|
context.files[context.param_name].close()
|
||||||
context.files[context.param_name] = open(context.file_name, 'rb')
|
context.files[context.param_name] = open(context.file_name, 'rb')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_black_box_image(file_name, size):
|
def create_black_box_image(file_name, size):
|
||||||
can = canvas.Canvas(file_name, pagesize=size)
|
can = canvas.Canvas(file_name, pagesize=size)
|
||||||
width, height = size
|
width, height = size
|
||||||
@@ -75,25 +76,9 @@ def create_black_box_image(file_name, size):
|
|||||||
can.showPage()
|
can.showPage()
|
||||||
can.save()
|
can.save()
|
||||||
|
|
||||||
@given(u'the pdf contains {image_count:d} images of size {width:d}x{height:d} on {page_count:d} pages')
|
def create_pdf_with_black_boxes(file_name, image_count, page_count):
|
||||||
def step_impl(context, image_count, width, height, page_count):
|
page_width, page_height = letter
|
||||||
context.param_name = "fileInput"
|
box_size = 72 # 1 inch by 1 inch black box
|
||||||
context.file_name = "genericNonCustomisableName.pdf"
|
|
||||||
create_pdf_with_images_and_boxes(context.file_name, image_count, page_count, width, height)
|
|
||||||
if not hasattr(context, 'files'):
|
|
||||||
context.files = {}
|
|
||||||
context.files[context.param_name] = open(context.file_name, 'rb')
|
|
||||||
|
|
||||||
def add_black_boxes_to_image(image):
|
|
||||||
if isinstance(image, str):
|
|
||||||
image = Image.open(image)
|
|
||||||
|
|
||||||
draw = ImageDraw.Draw(image)
|
|
||||||
draw.rectangle([(0, 0), image.size], fill=(0, 0, 0)) # Fill image with black
|
|
||||||
return image
|
|
||||||
|
|
||||||
def create_pdf_with_images_and_boxes(file_name, image_count, page_count, image_width, image_height):
|
|
||||||
page_width, page_height = max(letter[0], image_width), max(letter[1], image_height)
|
|
||||||
boxes_per_page = image_count // page_count + (1 if image_count % page_count != 0 else 0)
|
boxes_per_page = image_count // page_count + (1 if image_count % page_count != 0 else 0)
|
||||||
|
|
||||||
writer = PdfWriter()
|
writer = PdfWriter()
|
||||||
@@ -101,31 +86,15 @@ def create_pdf_with_images_and_boxes(file_name, image_count, page_count, image_w
|
|||||||
|
|
||||||
for page in range(page_count):
|
for page in range(page_count):
|
||||||
packet = io.BytesIO()
|
packet = io.BytesIO()
|
||||||
can = canvas.Canvas(packet, pagesize=(page_width, page_height))
|
can = canvas.Canvas(packet, pagesize=letter)
|
||||||
|
|
||||||
for i in range(boxes_per_page):
|
for i in range(boxes_per_page):
|
||||||
if box_counter >= image_count:
|
if box_counter >= image_count:
|
||||||
break
|
break
|
||||||
|
x = (i % (page_width // box_size)) * box_size
|
||||||
# Simulating a dynamic image creation (replace this with your actual image creation logic)
|
y = page_height - ((i // (page_width // box_size) + 1) * box_size)
|
||||||
# For demonstration, we'll create a simple black image
|
can.setFillColorRGB(0, 0, 0)
|
||||||
dummy_image = Image.new('RGB', (image_width, image_height), color='white') # Create a white image
|
can.rect(x, y, box_size, box_size, fill=1)
|
||||||
dummy_image = add_black_boxes_to_image(dummy_image) # Add black boxes
|
|
||||||
|
|
||||||
# Convert the PIL Image to bytes to pass to drawImage
|
|
||||||
image_bytes = io.BytesIO()
|
|
||||||
dummy_image.save(image_bytes, format='PNG')
|
|
||||||
image_bytes.seek(0)
|
|
||||||
|
|
||||||
# Check if the image fits in the current page dimensions
|
|
||||||
x = (i % (page_width // image_width)) * image_width
|
|
||||||
y = page_height - (((i % (page_height // image_height)) + 1) * image_height)
|
|
||||||
|
|
||||||
if x + image_width > page_width or y < 0:
|
|
||||||
break
|
|
||||||
|
|
||||||
# Add the image to the PDF
|
|
||||||
can.drawImage(ImageReader(image_bytes), x, y, width=image_width, height=image_height)
|
|
||||||
box_counter += 1
|
box_counter += 1
|
||||||
|
|
||||||
can.showPage()
|
can.showPage()
|
||||||
@@ -134,16 +103,9 @@ def create_pdf_with_images_and_boxes(file_name, image_count, page_count, image_w
|
|||||||
new_pdf = PdfReader(packet)
|
new_pdf = PdfReader(packet)
|
||||||
writer.add_page(new_pdf.pages[0])
|
writer.add_page(new_pdf.pages[0])
|
||||||
|
|
||||||
# Write the PDF to file
|
|
||||||
with open(file_name, 'wb') as f:
|
with open(file_name, 'wb') as f:
|
||||||
writer.write(f)
|
writer.write(f)
|
||||||
|
|
||||||
# Clean up temporary image files
|
|
||||||
for i in range(image_count):
|
|
||||||
temp_image_path = f"temp_image_{i}.png"
|
|
||||||
if os.path.exists(temp_image_path):
|
|
||||||
os.remove(temp_image_path)
|
|
||||||
|
|
||||||
@given('the pdf contains {image_count:d} images on {page_count:d} pages')
|
@given('the pdf contains {image_count:d} images on {page_count:d} pages')
|
||||||
def step_pdf_contains_images(context, image_count, page_count):
|
def step_pdf_contains_images(context, image_count, page_count):
|
||||||
if not hasattr(context, 'param_name'):
|
if not hasattr(context, 'param_name'):
|
||||||
@@ -156,6 +118,7 @@ def step_pdf_contains_images(context, image_count, page_count):
|
|||||||
context.files[context.param_name].close()
|
context.files[context.param_name].close()
|
||||||
context.files[context.param_name] = open(context.file_name, 'rb')
|
context.files[context.param_name] = open(context.file_name, 'rb')
|
||||||
|
|
||||||
|
|
||||||
@given('the pdf contains {page_count:d} pages with random text')
|
@given('the pdf contains {page_count:d} pages with random text')
|
||||||
def step_pdf_contains_pages_with_random_text(context, page_count):
|
def step_pdf_contains_pages_with_random_text(context, page_count):
|
||||||
buffer = io.BytesIO()
|
buffer = io.BytesIO()
|
||||||
@@ -223,21 +186,6 @@ def save_generated_pdf(context, filename):
|
|||||||
# WHEN #
|
# WHEN #
|
||||||
########
|
########
|
||||||
|
|
||||||
@when('I send a GET request to "{endpoint}"')
|
|
||||||
def step_send_get_request(context, endpoint):
|
|
||||||
base_url = "http://localhost:8080"
|
|
||||||
full_url = f"{base_url}{endpoint}"
|
|
||||||
response = requests.get(full_url)
|
|
||||||
context.response = response
|
|
||||||
|
|
||||||
@when('I send a GET request to "{endpoint}" with parameters')
|
|
||||||
def step_send_get_request_with_params(context, endpoint):
|
|
||||||
base_url = "http://localhost:8080"
|
|
||||||
params = {row['parameter']: row['value'] for row in context.table}
|
|
||||||
full_url = f"{base_url}{endpoint}"
|
|
||||||
response = requests.get(full_url, params=params)
|
|
||||||
context.response = response
|
|
||||||
|
|
||||||
@when('I send the API request to the endpoint "{endpoint}"')
|
@when('I send the API request to the endpoint "{endpoint}"')
|
||||||
def step_send_api_request(context, endpoint):
|
def step_send_api_request(context, endpoint):
|
||||||
url = f"http://localhost:8080{endpoint}"
|
url = f"http://localhost:8080{endpoint}"
|
||||||
@@ -330,6 +278,7 @@ def step_save_response_file(context, filename):
|
|||||||
f.write(context.response.content)
|
f.write(context.response.content)
|
||||||
print(f"Saved response content to {filename}")
|
print(f"Saved response content to {filename}")
|
||||||
|
|
||||||
|
|
||||||
@then('the response PDF should contain {page_count:d} pages')
|
@then('the response PDF should contain {page_count:d} pages')
|
||||||
def step_check_response_pdf_page_count(context, page_count):
|
def step_check_response_pdf_page_count(context, page_count):
|
||||||
response_file = io.BytesIO(context.response.content)
|
response_file = io.BytesIO(context.response.content)
|
||||||
@@ -356,26 +305,3 @@ def step_check_response_zip_doc_page_count(context, doc_count, pages_per_doc):
|
|||||||
reader = PdfReader(pdf_file)
|
reader = PdfReader(pdf_file)
|
||||||
actual_pages_per_doc = len(reader.pages)
|
actual_pages_per_doc = len(reader.pages)
|
||||||
assert actual_pages_per_doc == pages_per_doc, f"Expected {pages_per_doc} pages per document but got {actual_pages_per_doc} pages in document {file_name}"
|
assert actual_pages_per_doc == pages_per_doc, f"Expected {pages_per_doc} pages per document but got {actual_pages_per_doc} pages in document {file_name}"
|
||||||
|
|
||||||
@then('the JSON value of "{key}" should be "{expected_value}"')
|
|
||||||
def step_check_json_value(context, key, expected_value):
|
|
||||||
actual_value = context.response.json().get(key)
|
|
||||||
assert actual_value == expected_value, \
|
|
||||||
f"Expected JSON value for '{key}' to be '{expected_value}' but got '{actual_value}'"
|
|
||||||
|
|
||||||
@then('JSON list entry containing "{identifier_key}" as "{identifier_value}" should have "{target_key}" as "{target_value}"')
|
|
||||||
def step_check_json_list_entry(context, identifier_key, identifier_self, target_key, target_value):
|
|
||||||
json_response = context.response.json()
|
|
||||||
for entry in json_response:
|
|
||||||
if entry.get(identifier_key) == identifier_value:
|
|
||||||
assert entry.get(target_key) == target_value, \
|
|
||||||
f"Expected {target_key} to be {target_value} in entry where {identifier_key} is {identifier_value}, but found {entry.get(target_key)}"
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
raise AssertionError(f"No entry with {identifier_key} as {identifier_value} found")
|
|
||||||
|
|
||||||
@then('the response should match the regex "{pattern}"')
|
|
||||||
def step_response_matches_regex(context, pattern):
|
|
||||||
response_text = context.response.text
|
|
||||||
assert re.match(pattern, response_text), \
|
|
||||||
f"Response '{response_text}' does not match the expected pattern '{pattern}'"
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ services:
|
|||||||
DOCKER_ENABLE_SECURITY: "false"
|
DOCKER_ENABLE_SECURITY: "false"
|
||||||
SECURITY_ENABLELOGIN: "false"
|
SECURITY_ENABLELOGIN: "false"
|
||||||
LANGS: "en_GB,en_US,ar_AR,de_DE,fr_FR,es_ES,zh_CN,zh_TW,ca_CA,it_IT,sv_SE,pl_PL,ro_RO,ko_KR,pt_BR,ru_RU,el_GR,hi_IN,hu_HU,tr_TR,id_ID"
|
LANGS: "en_GB,en_US,ar_AR,de_DE,fr_FR,es_ES,zh_CN,zh_TW,ca_CA,it_IT,sv_SE,pl_PL,ro_RO,ko_KR,pt_BR,ru_RU,el_GR,hi_IN,hu_HU,tr_TR,id_ID"
|
||||||
|
INSTALL_BOOK_AND_ADVANCED_HTML_OPS: "true"
|
||||||
SYSTEM_DEFAULTLOCALE: en-US
|
SYSTEM_DEFAULTLOCALE: en-US
|
||||||
UI_APPNAME: Stirling-PDF
|
UI_APPNAME: Stirling-PDF
|
||||||
UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest
|
UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest
|
||||||
|
|||||||
@@ -25,11 +25,6 @@ ignore = [
|
|||||||
'text',
|
'text',
|
||||||
]
|
]
|
||||||
|
|
||||||
[da_DK]
|
|
||||||
ignore = [
|
|
||||||
'language.direction',
|
|
||||||
]
|
|
||||||
|
|
||||||
[de_DE]
|
[de_DE]
|
||||||
ignore = [
|
ignore = [
|
||||||
'AddStampRequest.alphabet',
|
'AddStampRequest.alphabet',
|
||||||
@@ -92,11 +87,6 @@ ignore = [
|
|||||||
'watermark.type.2',
|
'watermark.type.2',
|
||||||
]
|
]
|
||||||
|
|
||||||
[ga_IE]
|
|
||||||
ignore = [
|
|
||||||
'language.direction',
|
|
||||||
]
|
|
||||||
|
|
||||||
[hi_IN]
|
[hi_IN]
|
||||||
ignore = [
|
ignore = [
|
||||||
'language.direction',
|
'language.direction',
|
||||||
@@ -222,14 +212,6 @@ ignore = [
|
|||||||
'language.direction',
|
'language.direction',
|
||||||
]
|
]
|
||||||
|
|
||||||
[th_TH]
|
|
||||||
ignore = [
|
|
||||||
'language.direction',
|
|
||||||
'pipeline.title',
|
|
||||||
'pipelineOptions.pipelineHeader',
|
|
||||||
'showJS.tags',
|
|
||||||
]
|
|
||||||
|
|
||||||
[tr_TR]
|
[tr_TR]
|
||||||
ignore = [
|
ignore = [
|
||||||
'language.direction',
|
'language.direction',
|
||||||
@@ -240,14 +222,6 @@ ignore = [
|
|||||||
'language.direction',
|
'language.direction',
|
||||||
]
|
]
|
||||||
|
|
||||||
[vi_VN]
|
|
||||||
ignore = [
|
|
||||||
'language.direction',
|
|
||||||
'pipeline.title',
|
|
||||||
'pipelineOptions.pipelineHeader',
|
|
||||||
'showJS.tags',
|
|
||||||
]
|
|
||||||
|
|
||||||
[zh_CN]
|
[zh_CN]
|
||||||
ignore = [
|
ignore = [
|
||||||
'language.direction',
|
'language.direction',
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ fi
|
|||||||
umask "$UMASK" || true
|
umask "$UMASK" || true
|
||||||
|
|
||||||
if [[ "$INSTALL_BOOK_AND_ADVANCED_HTML_OPS" == "true" && "$FAT_DOCKER" != "true" ]]; then
|
if [[ "$INSTALL_BOOK_AND_ADVANCED_HTML_OPS" == "true" && "$FAT_DOCKER" != "true" ]]; then
|
||||||
echo "issue with calibre in current version, feature currently disabled on Stirling-PDF"
|
apk add --no-cache calibre@testing
|
||||||
#apk add --no-cache calibre@testing
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$FAT_DOCKER" != "true" ]]; then
|
if [[ "$FAT_DOCKER" != "true" ]]; then
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public class SPdfApplication {
|
|||||||
// Check if the BROWSER_OPEN environment variable is set to true
|
// Check if the BROWSER_OPEN environment variable is set to true
|
||||||
String browserOpenEnv = env.getProperty("BROWSER_OPEN");
|
String browserOpenEnv = env.getProperty("BROWSER_OPEN");
|
||||||
boolean browserOpen = browserOpenEnv != null && "true".equalsIgnoreCase(browserOpenEnv);
|
boolean browserOpen = browserOpenEnv != null && "true".equalsIgnoreCase(browserOpenEnv);
|
||||||
|
|
||||||
if (browserOpen) {
|
if (browserOpen) {
|
||||||
try {
|
try {
|
||||||
String url = "http://localhost:" + getNonStaticPort();
|
String url = "http://localhost:" + getNonStaticPort();
|
||||||
@@ -78,13 +79,13 @@ public class SPdfApplication {
|
|||||||
|
|
||||||
// custom javs settings file
|
// custom javs settings file
|
||||||
if (Files.exists(Paths.get("configs/custom_settings.yml"))) {
|
if (Files.exists(Paths.get("configs/custom_settings.yml"))) {
|
||||||
String existingLocation = propertyFiles.getOrDefault("spring.config.additional-location", "");
|
String existing = propertyFiles.getOrDefault("spring.config.additional-location", "");
|
||||||
if (!existingLocation.isEmpty()) {
|
if (!existing.isEmpty()) {
|
||||||
existingLocation += ",";
|
existing += ",";
|
||||||
}
|
}
|
||||||
propertyFiles.put(
|
propertyFiles.put(
|
||||||
"spring.config.additional-location",
|
"spring.config.additional-location",
|
||||||
existingLocation + "file:configs/custom_settings.yml");
|
existing + "file:configs/custom_settings.yml");
|
||||||
} else {
|
} else {
|
||||||
logger.warn("Custom configuration file 'configs/custom_settings.yml' does not exist.");
|
logger.warn("Custom configuration file 'configs/custom_settings.yml' does not exist.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,25 +32,25 @@ public class CleanUrlInterceptor implements HandlerInterceptor {
|
|||||||
String queryString = request.getQueryString();
|
String queryString = request.getQueryString();
|
||||||
if (queryString != null && !queryString.isEmpty()) {
|
if (queryString != null && !queryString.isEmpty()) {
|
||||||
String requestURI = request.getRequestURI();
|
String requestURI = request.getRequestURI();
|
||||||
Map<String, String> allowedParameters = new HashMap<>();
|
Map<String, String> parameters = new HashMap<>();
|
||||||
|
|
||||||
// Keep only the allowed parameters
|
// Keep only the allowed parameters
|
||||||
String[] queryParameters = queryString.split("&");
|
String[] queryParameters = queryString.split("&");
|
||||||
for (String param : queryParameters) {
|
for (String param : queryParameters) {
|
||||||
String[] keyValuePair = param.split("=");
|
String[] keyValue = param.split("=");
|
||||||
if (keyValuePair.length != 2) {
|
if (keyValue.length != 2) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ALLOWED_PARAMS.contains(keyValuePair[0])) {
|
if (ALLOWED_PARAMS.contains(keyValue[0])) {
|
||||||
allowedParameters.put(keyValuePair[0], keyValuePair[1]);
|
parameters.put(keyValue[0], keyValue[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are any parameters that are not allowed
|
// If there are any parameters that are not allowed
|
||||||
if (allowedParameters.size() != queryParameters.length) {
|
if (parameters.size() != queryParameters.length) {
|
||||||
// Construct new query string
|
// Construct new query string
|
||||||
StringBuilder newQueryString = new StringBuilder();
|
StringBuilder newQueryString = new StringBuilder();
|
||||||
for (Map.Entry<String, String> entry : allowedParameters.entrySet()) {
|
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||||
if (newQueryString.length() > 0) {
|
if (newQueryString.length() > 0) {
|
||||||
newQueryString.append("&");
|
newQueryString.append("&");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import java.nio.file.Paths;
|
|||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
@@ -132,12 +131,11 @@ public class DatabaseBackupHelper implements DatabaseBackupInterface {
|
|||||||
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
|
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
|
||||||
Path insertOutputFilePath =
|
Path insertOutputFilePath =
|
||||||
this.getBackupFilePath("backup_" + dateNow.format(myFormatObj) + ".sql");
|
this.getBackupFilePath("backup_" + dateNow.format(myFormatObj) + ".sql");
|
||||||
String query = "SCRIPT SIMPLE COLUMNS DROP to ?;";
|
String query = "SCRIPT SIMPLE COLUMNS DROP to '" + insertOutputFilePath.toString() + "';";
|
||||||
|
|
||||||
try (Connection conn = DriverManager.getConnection(url, "sa", "");
|
try (Connection conn = DriverManager.getConnection(url, "sa", "");
|
||||||
PreparedStatement stmt = conn.prepareStatement(query)) {
|
Statement stmt = conn.createStatement()) {
|
||||||
stmt.setString(1, insertOutputFilePath.toString());
|
stmt.execute(query);
|
||||||
stmt.execute();
|
|
||||||
log.info("Database export completed: {}", insertOutputFilePath);
|
log.info("Database export completed: {}", insertOutputFilePath);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Error during database export: {}", e.getMessage(), e);
|
log.error("Error during database export: {}", e.getMessage(), e);
|
||||||
@@ -179,12 +177,11 @@ public class DatabaseBackupHelper implements DatabaseBackupInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean executeDatabaseScript(Path scriptPath) {
|
private boolean executeDatabaseScript(Path scriptPath) {
|
||||||
String query = "RUNSCRIPT from ?;";
|
|
||||||
|
|
||||||
try (Connection conn = DriverManager.getConnection(url, "sa", "");
|
try (Connection conn = DriverManager.getConnection(url, "sa", "");
|
||||||
PreparedStatement stmt = conn.prepareStatement(query)) {
|
Statement stmt = conn.createStatement()) {
|
||||||
stmt.setString(1, scriptPath.toString());
|
|
||||||
stmt.execute();
|
String query = "RUNSCRIPT from '" + scriptPath.toString() + "';";
|
||||||
|
stmt.execute(query);
|
||||||
log.info("Database import completed: {}", scriptPath);
|
log.info("Database import completed: {}", scriptPath);
|
||||||
return true;
|
return true;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package stirling.software.SPDF.controller.api.misc;
|
package stirling.software.SPDF.controller.api.misc;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.stream.Collectors;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
import org.apache.pdfbox.Loader;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
@@ -17,7 +17,6 @@ import org.apache.pdfbox.text.PDFTextStripper;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.http.HttpStatus;
|
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.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -51,31 +50,31 @@ public class BlankPageController {
|
|||||||
int threshold = request.getThreshold();
|
int threshold = request.getThreshold();
|
||||||
float whitePercent = request.getWhitePercent();
|
float whitePercent = request.getWhitePercent();
|
||||||
|
|
||||||
try (PDDocument document = Loader.loadPDF(inputFile.getBytes())) {
|
PDDocument document = null;
|
||||||
|
try {
|
||||||
|
document = Loader.loadPDF(inputFile.getBytes());
|
||||||
PDPageTree pages = document.getDocumentCatalog().getPages();
|
PDPageTree pages = document.getDocumentCatalog().getPages();
|
||||||
PDFTextStripper textStripper = new PDFTextStripper();
|
PDFTextStripper textStripper = new PDFTextStripper();
|
||||||
|
|
||||||
List<PDPage> nonBlankPages = new ArrayList<>();
|
List<Integer> pagesToKeepIndex = new ArrayList<>();
|
||||||
List<PDPage> blankPages = new ArrayList<>();
|
|
||||||
int pageIndex = 0;
|
int pageIndex = 0;
|
||||||
|
|
||||||
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||||
pdfRenderer.setSubsamplingAllowed(true);
|
pdfRenderer.setSubsamplingAllowed(true);
|
||||||
for (PDPage page : pages) {
|
for (PDPage page : pages) {
|
||||||
logger.info("checking page {}", pageIndex);
|
logger.info("checking page " + pageIndex);
|
||||||
textStripper.setStartPage(pageIndex + 1);
|
textStripper.setStartPage(pageIndex + 1);
|
||||||
textStripper.setEndPage(pageIndex + 1);
|
textStripper.setEndPage(pageIndex + 1);
|
||||||
String pageText = textStripper.getText(document);
|
String pageText = textStripper.getText(document);
|
||||||
boolean hasText = !pageText.trim().isEmpty();
|
boolean hasText = !pageText.trim().isEmpty();
|
||||||
|
|
||||||
boolean blank = true;
|
Boolean blank = true;
|
||||||
if (hasText) {
|
if (hasText) {
|
||||||
logger.info("page {} has text, not blank", pageIndex);
|
logger.info("page " + pageIndex + " has text, not blank");
|
||||||
blank = false;
|
blank = false;
|
||||||
} else {
|
} else {
|
||||||
boolean hasImages = PdfUtils.hasImagesOnPage(page);
|
boolean hasImages = PdfUtils.hasImagesOnPage(page);
|
||||||
if (hasImages) {
|
if (hasImages) {
|
||||||
logger.info("page {} has image, running blank detection", pageIndex);
|
logger.info("page " + pageIndex + " has image, running blank detection");
|
||||||
// Render image and save as temp file
|
// Render image and save as temp file
|
||||||
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 30);
|
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 30);
|
||||||
blank = isBlankImage(image, threshold, whitePercent, threshold);
|
blank = isBlankImage(image, threshold, whitePercent, threshold);
|
||||||
@@ -83,57 +82,34 @@ public class BlankPageController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (blank) {
|
if (blank) {
|
||||||
logger.info("Skipping, Image was blank for page #{}", pageIndex);
|
logger.info("Skipping, Image was blank for page #" + pageIndex);
|
||||||
blankPages.add(page);
|
|
||||||
} else {
|
} else {
|
||||||
logger.info("page {} has image which is not blank", pageIndex);
|
logger.info("page " + pageIndex + " has image which is not blank");
|
||||||
nonBlankPages.add(page);
|
pagesToKeepIndex.add(pageIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
pageIndex++;
|
pageIndex++;
|
||||||
}
|
}
|
||||||
|
// Remove pages not present in pagesToKeepIndex
|
||||||
|
List<Integer> pageIndices =
|
||||||
|
IntStream.range(0, pages.getCount()).boxed().collect(Collectors.toList());
|
||||||
|
Collections.reverse(pageIndices); // Reverse to prevent index shifting during removal
|
||||||
|
for (Integer i : pageIndices) {
|
||||||
|
if (!pagesToKeepIndex.contains(i)) {
|
||||||
|
pages.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
return WebResponseUtils.pdfDocToWebResponse(
|
||||||
ZipOutputStream zos = new ZipOutputStream(baos);
|
document,
|
||||||
|
|
||||||
String filename =
|
|
||||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||||
.replaceFirst("[.][^.]+$", "");
|
.replaceFirst("[.][^.]+$", "")
|
||||||
|
+ "_blanksRemoved.pdf");
|
||||||
if (!nonBlankPages.isEmpty()) {
|
|
||||||
createZipEntry(zos, nonBlankPages, filename + "_nonBlankPages.pdf");
|
|
||||||
} else {
|
|
||||||
createZipEntry(zos, blankPages, filename + "_allBlankPages.pdf");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nonBlankPages.isEmpty() && !blankPages.isEmpty()) {
|
|
||||||
createZipEntry(zos, blankPages, filename + "_blankPages.pdf");
|
|
||||||
}
|
|
||||||
|
|
||||||
zos.close();
|
|
||||||
|
|
||||||
logger.info("Returning ZIP file: {}", filename + "_processed.zip");
|
|
||||||
return WebResponseUtils.boasToWebResponse(
|
|
||||||
baos, filename + "_processed.zip", MediaType.APPLICATION_OCTET_STREAM);
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error("exception", e);
|
logger.error("exception", e);
|
||||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
} finally {
|
||||||
}
|
if (document != null) document.close();
|
||||||
|
|
||||||
public void createZipEntry(ZipOutputStream zos, List<PDPage> pages, String entryName)
|
|
||||||
throws IOException {
|
|
||||||
try (PDDocument document = new PDDocument()) {
|
|
||||||
|
|
||||||
for (PDPage page : pages) {
|
|
||||||
document.addPage(page);
|
|
||||||
}
|
|
||||||
|
|
||||||
ZipEntry zipEntry = new ZipEntry(entryName);
|
|
||||||
zos.putNextEntry(zipEntry);
|
|
||||||
document.save(zos);
|
|
||||||
zos.closeEntry();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public class CompressController {
|
|||||||
List<String> command = new ArrayList<>();
|
List<String> command = new ArrayList<>();
|
||||||
command.add("gs");
|
command.add("gs");
|
||||||
command.add("-sDEVICE=pdfwrite");
|
command.add("-sDEVICE=pdfwrite");
|
||||||
command.add("-dCompatibilityLevel=1.5");
|
command.add("-dCompatibilityLevel=1.4");
|
||||||
|
|
||||||
switch (optimizeLevel) {
|
switch (optimizeLevel) {
|
||||||
case 1:
|
case 1:
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ public class PasswordController {
|
|||||||
boolean canModifyAnnotations = request.isCanModifyAnnotations();
|
boolean canModifyAnnotations = request.isCanModifyAnnotations();
|
||||||
boolean canPrint = request.isCanPrint();
|
boolean canPrint = request.isCanPrint();
|
||||||
boolean canPrintFaithful = request.isCanPrintFaithful();
|
boolean canPrintFaithful = request.isCanPrintFaithful();
|
||||||
|
|
||||||
PDDocument document = Loader.loadPDF(fileInput.getBytes());
|
PDDocument document = Loader.loadPDF(fileInput.getBytes());
|
||||||
AccessPermission ap = new AccessPermission();
|
AccessPermission ap = new AccessPermission();
|
||||||
ap.setCanAssembleDocument(!canAssembleDocument);
|
ap.setCanAssembleDocument(!canAssembleDocument);
|
||||||
|
|||||||
@@ -360,8 +360,6 @@ public class ApplicationProperties {
|
|||||||
+ useAsUsername
|
+ useAsUsername
|
||||||
+ ", provider="
|
+ ", provider="
|
||||||
+ provider
|
+ provider
|
||||||
+ ", client="
|
|
||||||
+ client
|
|
||||||
+ ", scopes="
|
+ ", scopes="
|
||||||
+ scopes
|
+ scopes
|
||||||
+ "]";
|
+ "]";
|
||||||
|
|||||||
@@ -3,11 +3,9 @@ package stirling.software.SPDF.repository;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.Authority;
|
import stirling.software.SPDF.model.Authority;
|
||||||
|
|
||||||
@Repository
|
|
||||||
public interface AuthorityRepository extends JpaRepository<Authority, Long> {
|
public interface AuthorityRepository extends JpaRepository<Authority, Long> {
|
||||||
// Set<Authority> findByUsername(String username);
|
// Set<Authority> findByUsername(String username);
|
||||||
Set<Authority> findByUser_Username(String username);
|
Set<Authority> findByUser_Username(String username);
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package stirling.software.SPDF.repository;
|
package stirling.software.SPDF.repository;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.PersistentLogin;
|
import stirling.software.SPDF.model.PersistentLogin;
|
||||||
|
|
||||||
@Repository
|
|
||||||
public interface PersistentLoginRepository extends JpaRepository<PersistentLogin, String> {}
|
public interface PersistentLoginRepository extends JpaRepository<PersistentLogin, String> {}
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ package stirling.software.SPDF.repository;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
|
|
||||||
@Repository
|
public interface UserRepository extends JpaRepository<User, String> {
|
||||||
public interface UserRepository extends JpaRepository<User, Long> {
|
|
||||||
Optional<User> findByUsernameIgnoreCase(String username);
|
Optional<User> findByUsernameIgnoreCase(String username);
|
||||||
|
|
||||||
Optional<User> findByUsername(String username);
|
Optional<User> findByUsername(String username);
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Покажи проследяване на стека
|
|||||||
error.copyStack=Копиране на проследяване на стека
|
error.copyStack=Копиране на проследяване на стека
|
||||||
error.githubSubmit=GitHub - Изпратете запитване
|
error.githubSubmit=GitHub - Изпратете запитване
|
||||||
error.discordSubmit=Discord - Изпратете запитване за поддръжка
|
error.discordSubmit=Discord - Изпратете запитване за поддръжка
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Zobrazit stopu zásobníku
|
|||||||
error.copyStack=Kopírovat stopu zásobníku
|
error.copyStack=Kopírovat stopu zásobníku
|
||||||
error.githubSubmit=GitHub - Odeslat požadavek
|
error.githubSubmit=GitHub - Odeslat požadavek
|
||||||
error.discordSubmit=Discord - Odeslat příspěvek podpory
|
error.discordSubmit=Discord - Odeslat příspěvek podpory
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1124,3 +1124,4 @@ error.showStack=Stack-Trace anzeigen
|
|||||||
error.copyStack=Stack-Trace kopieren
|
error.copyStack=Stack-Trace kopieren
|
||||||
error.githubSubmit=GitHub - Ein Ticket einreichen
|
error.githubSubmit=GitHub - Ein Ticket einreichen
|
||||||
error.discordSubmit=Discord - Unterstützungsbeitrag einreichen
|
error.discordSubmit=Discord - Unterstützungsbeitrag einreichen
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Εμφάνιση Stack Trace
|
|||||||
error.copyStack=Αντιγραφή Stack Trace
|
error.copyStack=Αντιγραφή Stack Trace
|
||||||
error.githubSubmit=GitHub - Υποβάλετε ένα ticket
|
error.githubSubmit=GitHub - Υποβάλετε ένα ticket
|
||||||
error.discordSubmit=Discord - Υποβάλετε ένα Support post
|
error.discordSubmit=Discord - Υποβάλετε ένα Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -60,11 +60,11 @@ deleteCurrentUserMessage=No puede eliminar el usuario que tiene la sesión actua
|
|||||||
deleteUsernameExistsMessage=El usuario no existe y no puede eliminarse.
|
deleteUsernameExistsMessage=El usuario no existe y no puede eliminarse.
|
||||||
downgradeCurrentUserMessage=No se puede degradar el rol del usuario actual
|
downgradeCurrentUserMessage=No se puede degradar el rol del usuario actual
|
||||||
downgradeCurrentUserLongMessage=No se puede degradar el rol del usuario actual. Por lo tanto, el usuario actual no se mostrará.
|
downgradeCurrentUserLongMessage=No se puede degradar el rol del usuario actual. Por lo tanto, el usuario actual no se mostrará.
|
||||||
userAlreadyExistsOAuthMessage=La usuario ya existe como usuario de OAuth2.
|
userAlreadyExistsOAuthMessage=The user already exists as an OAuth2 user.
|
||||||
userAlreadyExistsWebMessage=El usuario ya existe como usuario web.
|
userAlreadyExistsWebMessage=The user already exists as an web user.
|
||||||
error=Error
|
error=Error
|
||||||
oops=Ups!
|
oops=Ups!
|
||||||
help=Ayuda
|
help=Help
|
||||||
goHomepage=Ir a la página principal
|
goHomepage=Ir a la página principal
|
||||||
joinDiscord=Únase a nuestro servidor Discord
|
joinDiscord=Únase a nuestro servidor Discord
|
||||||
seeDockerHub=Ver Docker Hub
|
seeDockerHub=Ver Docker Hub
|
||||||
@@ -86,7 +86,7 @@ pipeline.defaultOption=Personalizar
|
|||||||
pipeline.submitButton=Enviar
|
pipeline.submitButton=Enviar
|
||||||
pipeline.help=Ayuda de Canalización
|
pipeline.help=Ayuda de Canalización
|
||||||
pipeline.scanHelp=Ayuda de escaneado de carpetas
|
pipeline.scanHelp=Ayuda de escaneado de carpetas
|
||||||
pipeline.deletePrompt=¿Estás segura de que quieres eliminar la canalización?
|
pipeline.deletePrompt=Are you sure you want to delete pipeline
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# Pipeline Options #
|
# Pipeline Options #
|
||||||
@@ -107,18 +107,18 @@ pipelineOptions.validateButton=Validar
|
|||||||
#############
|
#############
|
||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favoritos
|
navbar.favorite=Favorites
|
||||||
navbar.darkmode=Modo oscuro
|
navbar.darkmode=Modo oscuro
|
||||||
navbar.language=Idiomas
|
navbar.language=Languages
|
||||||
navbar.settings=Configuración
|
navbar.settings=Configuración
|
||||||
navbar.allTools=Herramientas
|
navbar.allTools=Tools
|
||||||
navbar.multiTool=Multi herramientas
|
navbar.multiTool=Multi Tools
|
||||||
navbar.sections.organize=Organize
|
navbar.sections.organize=Organize
|
||||||
navbar.sections.convertTo=Convertir a PDF
|
navbar.sections.convertTo=Convert to PDF
|
||||||
navbar.sections.convertFrom=Convertir desde PDF
|
navbar.sections.convertFrom=Convert from PDF
|
||||||
navbar.sections.security=Señalización y seguridad
|
navbar.sections.security=Sign & Security
|
||||||
navbar.sections.advance=Avanzado
|
navbar.sections.advance=Advanced
|
||||||
navbar.sections.edit=Ver y Editar
|
navbar.sections.edit=View & Edit
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# SETTINGS #
|
# SETTINGS #
|
||||||
@@ -175,8 +175,8 @@ adminUserSettings.header=Configuración de control de usuario administrador
|
|||||||
adminUserSettings.admin=Administrador
|
adminUserSettings.admin=Administrador
|
||||||
adminUserSettings.user=Usuario
|
adminUserSettings.user=Usuario
|
||||||
adminUserSettings.addUser=Añadir Nuevo Usuario
|
adminUserSettings.addUser=Añadir Nuevo Usuario
|
||||||
adminUserSettings.deleteUser=Eliminar Usuario
|
adminUserSettings.deleteUser=Delete User
|
||||||
adminUserSettings.confirmDeleteUser=¿Se debe eliminar al usuario?
|
adminUserSettings.confirmDeleteUser=Should the user be deleted?
|
||||||
adminUserSettings.usernameInfo=El nombre de usuario solo puede contener letras, números y los siguientes caracteres especiales @._+- o debe ser una dirección de correo electrónico válida.
|
adminUserSettings.usernameInfo=El nombre de usuario solo puede contener letras, números y los siguientes caracteres especiales @._+- o debe ser una dirección de correo electrónico válida.
|
||||||
adminUserSettings.roles=Roles
|
adminUserSettings.roles=Roles
|
||||||
adminUserSettings.role=Rol
|
adminUserSettings.role=Rol
|
||||||
@@ -189,24 +189,24 @@ adminUserSettings.internalApiUser=Usuario interno de API
|
|||||||
adminUserSettings.forceChange=Forzar usuario a cambiar usuario/contraseña en el acceso
|
adminUserSettings.forceChange=Forzar usuario a cambiar usuario/contraseña en el acceso
|
||||||
adminUserSettings.submit=Guardar Usuario
|
adminUserSettings.submit=Guardar Usuario
|
||||||
adminUserSettings.changeUserRole=Cambiar rol de usuario
|
adminUserSettings.changeUserRole=Cambiar rol de usuario
|
||||||
adminUserSettings.authenticated=Autenticado
|
adminUserSettings.authenticated=Authenticated
|
||||||
|
|
||||||
|
|
||||||
database.title=Base de Datos Importar/Exportar
|
database.title=Database Import/Export
|
||||||
database.header=Base de Datos Importar/Exportar
|
database.header=Database Import/Export
|
||||||
database.fileName=Nombre de Archivo
|
database.fileName=File Name
|
||||||
database.creationDate=Fecha de creación
|
database.creationDate=Creation Date
|
||||||
database.fileSize=Tamaño de archivo
|
database.fileSize=File Size
|
||||||
database.deleteBackupFile=Eliminar archivo de copia de seguridad
|
database.deleteBackupFile=Delete Backup File
|
||||||
database.importBackupFile=Importar archivo de copia de seguridad
|
database.importBackupFile=Import Backup File
|
||||||
database.downloadBackupFile=Descargar archivo de copia de seguridad
|
database.downloadBackupFile=Download Backup File
|
||||||
database.info_1=Al importar datos, es fundamental garantizar la estructura correcta. Si no está seguro de lo que está haciendo, busque consejo y apoyo de un profesional. Un error en la estructura puede causar un mal funcionamiento de la aplicación, incluyendo la imposibilidad total de ejecutar la aplicación.
|
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
|
||||||
database.info_2=El nombre del archivo no importa al cargarlo. Posteriormente se le cambiará el nombre para que siga el formato backup_user_yyyyMMddHHmm.sql, lo que garantiza una convención de nomenclatura coherente.
|
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
|
||||||
database.submit=Importar Backup
|
database.submit=Import Backup
|
||||||
database.importIntoDatabaseSuccessed=Importación a la base de datos ha sido exitosa
|
database.importIntoDatabaseSuccessed=Import into database successed
|
||||||
database.fileNotFound=Archivo no encontrado
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=El archivo no debe ser nulo o vacío.
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=Archivo de importación fallido
|
database.failedImportFile=Failed Import File
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# HOME-PAGE #
|
# HOME-PAGE #
|
||||||
@@ -353,8 +353,8 @@ home.certSign.title=Firmar con certificado
|
|||||||
home.certSign.desc=Firmar un PDF con un Certificado/Clave (PEM/P12)
|
home.certSign.desc=Firmar un PDF con un Certificado/Clave (PEM/P12)
|
||||||
certSign.tags=autentificar,PEM,P12,oficial,encriptar
|
certSign.tags=autentificar,PEM,P12,oficial,encriptar
|
||||||
|
|
||||||
home.removeCertSign.title=Quitar signo de certificado
|
home.removeCertSign.title=Remove Certificate Sign
|
||||||
home.removeCertSign.desc=Eliminar firma de certificado de PDF
|
home.removeCertSign.desc=Remove certificate signature from PDF
|
||||||
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
|
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
|
||||||
|
|
||||||
home.pageLayout.title=Diseño de varias páginas
|
home.pageLayout.title=Diseño de varias páginas
|
||||||
@@ -476,13 +476,13 @@ login.invalid=Nombre de usuario o contraseña erróneos.
|
|||||||
login.locked=Su cuenta se ha bloqueado.
|
login.locked=Su cuenta se ha bloqueado.
|
||||||
login.signinTitle=Por favor, inicie sesión
|
login.signinTitle=Por favor, inicie sesión
|
||||||
login.ssoSignIn=Iniciar sesión a través del inicio de sesión único
|
login.ssoSignIn=Iniciar sesión a través del inicio de sesión único
|
||||||
login.oauth2AutoCreateDisabled=Usuario de creación automática de OAUTH2 DESACTIVADO
|
login.oauth2AutoCreateDisabled=Usuario DE creación automática de OAUTH2 DESACTIVADO
|
||||||
login.oauth2RequestNotFound=Solicitud de autorización no encontrada
|
login.oauth2RequestNotFound=Authorization request not found
|
||||||
login.oauth2InvalidUserInfoResponse=Respuesta de información de usuario no válida
|
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
||||||
login.oauth2invalidRequest=Invalid Request
|
login.oauth2invalidRequest=Invalid Request
|
||||||
login.oauth2AccessDenied=Access Denied
|
login.oauth2AccessDenied=Access Denied
|
||||||
login.oauth2InvalidTokenResponse=Respuesta de token no válida
|
login.oauth2InvalidTokenResponse=Invalid Token Response
|
||||||
login.oauth2InvalidIdToken=Token de identificación no válido
|
login.oauth2InvalidIdToken=Invalid Id Token
|
||||||
|
|
||||||
|
|
||||||
#auto-redact
|
#auto-redact
|
||||||
@@ -681,10 +681,10 @@ certSign.submit=Firmar PDF
|
|||||||
|
|
||||||
|
|
||||||
#removeCertSign
|
#removeCertSign
|
||||||
removeCertSign.title=Eliminar firma del certificado
|
removeCertSign.title=Remove Certificate Signature
|
||||||
removeCertSign.header=Quitar el certificado digital del PDF
|
removeCertSign.header=Remove the digital certificate from the PDF
|
||||||
removeCertSign.selectPDF=Seleccione un archivo PDF:
|
removeCertSign.selectPDF=Select a PDF file:
|
||||||
removeCertSign.submit=Eliminar firma
|
removeCertSign.submit=Remove Signature
|
||||||
|
|
||||||
|
|
||||||
#removeBlanks
|
#removeBlanks
|
||||||
@@ -706,8 +706,8 @@ removeAnnotations.submit=Eliminar
|
|||||||
#compare
|
#compare
|
||||||
compare.title=Comparar
|
compare.title=Comparar
|
||||||
compare.header=Comparar archivos PDF
|
compare.header=Comparar archivos PDF
|
||||||
compare.highlightColor.1=Color resaltado 1:
|
compare.highlightColor.1=Highlight Color 1:
|
||||||
compare.highlightColor.2=Color resaltado 2:
|
compare.highlightColor.2=Highlight Color 2:
|
||||||
compare.document.1=Documento 1
|
compare.document.1=Documento 1
|
||||||
compare.document.2=Documento 2
|
compare.document.2=Documento 2
|
||||||
compare.submit=Comparar
|
compare.submit=Comparar
|
||||||
@@ -744,7 +744,7 @@ repair.submit=Reparar
|
|||||||
#flatten
|
#flatten
|
||||||
flatten.title=Aplanar
|
flatten.title=Aplanar
|
||||||
flatten.header=Acoplar archivos PDF
|
flatten.header=Acoplar archivos PDF
|
||||||
flatten.flattenOnlyForms=Aplanar sólo formularios
|
flatten.flattenOnlyForms=Flatten only forms
|
||||||
flatten.submit=Aplanar
|
flatten.submit=Aplanar
|
||||||
|
|
||||||
|
|
||||||
@@ -792,7 +792,7 @@ extractImages.submit=Extraer
|
|||||||
fileToPDF.title=Archivo a PDF
|
fileToPDF.title=Archivo a PDF
|
||||||
fileToPDF.header=Convertir cualquier archivo a PDF
|
fileToPDF.header=Convertir cualquier archivo a PDF
|
||||||
fileToPDF.credit=Este servicio usa LibreOffice y Unoconv para la conversión de archivos
|
fileToPDF.credit=Este servicio usa LibreOffice y Unoconv para la conversión de archivos
|
||||||
fileToPDF.supportedFileTypesInfo=Tipos de archivos admitidos
|
fileToPDF.supportedFileTypesInfo=Supported File types
|
||||||
fileToPDF.supportedFileTypes=Los tipos de archivo soportados deben incluir los indicados a continuación; sin embargo, para una completa y acutualizada lista de formatos soportados, por favor consulte la documentación de LibreOffice
|
fileToPDF.supportedFileTypes=Los tipos de archivo soportados deben incluir los indicados a continuación; sin embargo, para una completa y acutualizada lista de formatos soportados, por favor consulte la documentación de LibreOffice
|
||||||
fileToPDF.submit=Convertir a PDF
|
fileToPDF.submit=Convertir a PDF
|
||||||
|
|
||||||
@@ -1000,8 +1000,8 @@ pdfToPDFA.header=PDF a PDF/A
|
|||||||
pdfToPDFA.credit=Este servicio usa OCRmyPDF para la conversión a PDF/A
|
pdfToPDFA.credit=Este servicio usa OCRmyPDF para la conversión a PDF/A
|
||||||
pdfToPDFA.submit=Convertir
|
pdfToPDFA.submit=Convertir
|
||||||
pdfToPDFA.tip=Actualmente no funciona para múltiples entrada a la vez
|
pdfToPDFA.tip=Actualmente no funciona para múltiples entrada a la vez
|
||||||
pdfToPDFA.outputFormat=Formato de salida
|
pdfToPDFA.outputFormat=Output format
|
||||||
pdfToPDFA.pdfWithDigitalSignature=El PDF contiene una firma digital. Esto se eliminará en el siguiente paso.
|
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
|
||||||
|
|
||||||
|
|
||||||
#PDFToWord
|
#PDFToWord
|
||||||
@@ -1103,13 +1103,13 @@ licenses.version=Versión
|
|||||||
licenses.license=Licencia
|
licenses.license=Licencia
|
||||||
|
|
||||||
#survey
|
#survey
|
||||||
survey.nav=Encuesta
|
survey.nav=Survey
|
||||||
survey.title=Encuesta Stirling-PDF
|
survey.title=Stirling-PDF Survey
|
||||||
survey.description=Stirling-PDF no tiene seguimiento, por lo que queremos escuchar a nuestros usuarios para mejorar Stirling-PDF.
|
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
|
||||||
survey.please=¡Considere realizar nuestra encuesta!
|
survey.please=Please consider taking our survey!
|
||||||
survey.disabled=(La ventana emergente de la encuesta se desactivará en las siguientes actualizaciones, pero estará disponible al pie de la página.)
|
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
|
||||||
survey.button=Realizar encuesta
|
survey.button=Take Survey
|
||||||
survey.dontShowAgain=No volver a mostrar
|
survey.dontShowAgain=Don't show again
|
||||||
|
|
||||||
|
|
||||||
#error
|
#error
|
||||||
@@ -1124,3 +1124,4 @@ error.showStack=Mostrar seguimiento de pila
|
|||||||
error.copyStack=Mostrar seguimiento de pila
|
error.copyStack=Mostrar seguimiento de pila
|
||||||
error.githubSubmit=GitHub - Enviar un ticket
|
error.githubSubmit=GitHub - Enviar un ticket
|
||||||
error.discordSubmit=Discord - Enviar mensaje de soporte
|
error.discordSubmit=Discord - Enviar mensaje de soporte
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Afficher la Stack Trace
|
|||||||
error.copyStack=Copier la Stack Trace
|
error.copyStack=Copier la Stack Trace
|
||||||
error.githubSubmit=GitHub - Créer un ticket
|
error.githubSubmit=GitHub - Créer un ticket
|
||||||
error.discordSubmit=Discord - Poster un message de demande d’assistance
|
error.discordSubmit=Discord - Poster un message de demande d’assistance
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Prikaži Stack Trace
|
|||||||
error.copyStack=Kopiraj Stack Trace
|
error.copyStack=Kopiraj Stack Trace
|
||||||
error.githubSubmit=GitHub - Pošaljite ticket
|
error.githubSubmit=GitHub - Pošaljite ticket
|
||||||
error.discordSubmit=Discord - Pošalji objavu podrške
|
error.discordSubmit=Discord - Pošalji objavu podrške
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -706,8 +706,8 @@ removeAnnotations.submit=Rimuovi
|
|||||||
#compare
|
#compare
|
||||||
compare.title=Compara
|
compare.title=Compara
|
||||||
compare.header=Compara PDF
|
compare.header=Compara PDF
|
||||||
compare.highlightColor.1=Evidenzia colore 1:
|
compare.highlightColor.1=Highlight Color 1:
|
||||||
compare.highlightColor.2=Evidenzia colore 2:
|
compare.highlightColor.2=Highlight Color 2:
|
||||||
compare.document.1=Documento 1
|
compare.document.1=Documento 1
|
||||||
compare.document.2=Documento 2
|
compare.document.2=Documento 2
|
||||||
compare.submit=Compara
|
compare.submit=Compara
|
||||||
@@ -1124,3 +1124,4 @@ error.showStack=Mostra traccia dello stack
|
|||||||
error.copyStack=Copia traccia dello stack
|
error.copyStack=Copia traccia dello stack
|
||||||
error.githubSubmit=GitHub: invia un ticket
|
error.githubSubmit=GitHub: invia un ticket
|
||||||
error.discordSubmit=Discord: invia post di supporto
|
error.discordSubmit=Discord: invia post di supporto
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=スタックトレースを表示
|
|||||||
error.copyStack=スタックトレースをコピー
|
error.copyStack=スタックトレースをコピー
|
||||||
error.githubSubmit=GitHub - チケットを提出
|
error.githubSubmit=GitHub - チケットを提出
|
||||||
error.discordSubmit=Discord - サポート投稿を提出
|
error.discordSubmit=Discord - サポート投稿を提出
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=스택 추적 보기
|
|||||||
error.copyStack=스택 추적 복사
|
error.copyStack=스택 추적 복사
|
||||||
error.githubSubmit=GitHub - 티켓 제출
|
error.githubSubmit=GitHub - 티켓 제출
|
||||||
error.discordSubmit=Discord - 문의 게시
|
error.discordSubmit=Discord - 문의 게시
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Geeft tracering weer
|
|||||||
error.copyStack=Kopieer tracering
|
error.copyStack=Kopieer tracering
|
||||||
error.githubSubmit=GitHub - Dien een ticket in
|
error.githubSubmit=GitHub - Dien een ticket in
|
||||||
error.discordSubmit=Discord - Maak een support post
|
error.discordSubmit=Discord - Maak een support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Vis stakksporing
|
|||||||
error.copyStack=Kopier stakksporing
|
error.copyStack=Kopier stakksporing
|
||||||
error.githubSubmit=GitHub - Send inn en billett
|
error.githubSubmit=GitHub - Send inn en billett
|
||||||
error.discordSubmit=Discord - Send inn støtteinnlegg
|
error.discordSubmit=Discord - Send inn støtteinnlegg
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Pokaż Stack Trace
|
|||||||
error.copyStack=Kopiuj Stack Trace
|
error.copyStack=Kopiuj Stack Trace
|
||||||
error.githubSubmit=GitHub - wyślij zgłoszenie
|
error.githubSubmit=GitHub - wyślij zgłoszenie
|
||||||
error.discordSubmit=Discord - wyślij posta z prośbą o pomoc
|
error.discordSubmit=Discord - wyślij posta z prośbą o pomoc
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Показать стек вызовов
|
|||||||
error.copyStack=Скопировать стек вызовов
|
error.copyStack=Скопировать стек вызовов
|
||||||
error.githubSubmit=GitHub - Отправить заявку
|
error.githubSubmit=GitHub - Отправить заявку
|
||||||
error.discordSubmit=Discord - Отправить запрос в поддержку
|
error.discordSubmit=Discord - Отправить запрос в поддержку
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Zobraziť sledovanie zásobníka
|
|||||||
error.copyStack=Kopírovať sledovanie zásobníka
|
error.copyStack=Kopírovať sledovanie zásobníka
|
||||||
error.githubSubmit=GitHub - Podajte tiket
|
error.githubSubmit=GitHub - Podajte tiket
|
||||||
error.discordSubmit=Discord - Podajte príspevok na podporu
|
error.discordSubmit=Discord - Podajte príspevok na podporu
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Show Stack Trace
|
|||||||
error.copyStack=Copy Stack Trace
|
error.copyStack=Copy Stack Trace
|
||||||
error.githubSubmit=GitHub - Submit a ticket
|
error.githubSubmit=GitHub - Submit a ticket
|
||||||
error.discordSubmit=Discord - Submit Support post
|
error.discordSubmit=Discord - Submit Support post
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -55,7 +55,7 @@ userNotFoundMessage=Kullanıcı bulunamadı.
|
|||||||
incorrectPasswordMessage=Mevcut şifre yanlış.
|
incorrectPasswordMessage=Mevcut şifre yanlış.
|
||||||
usernameExistsMessage=Yeni Kullanıcı Adı zaten var.
|
usernameExistsMessage=Yeni Kullanıcı Adı zaten var.
|
||||||
invalidUsernameMessage=Geçersiz kullanıcı adı, kullanıcı adı yalnızca harf, rakam ve aşağıdaki özel karakterleri @._+- içerebilir veya geçerli bir e-posta adresi olmalıdır.
|
invalidUsernameMessage=Geçersiz kullanıcı adı, kullanıcı adı yalnızca harf, rakam ve aşağıdaki özel karakterleri @._+- içerebilir veya geçerli bir e-posta adresi olmalıdır.
|
||||||
confirmPasswordErrorMessage=Yeni Şifre ve Yeni Şifreyi Onayla eşleşmelidir.
|
confirmPasswordErrorMessage=New Password and Confirm New Password must match.
|
||||||
deleteCurrentUserMessage=Şu anda oturum açmış olan kullanıcı silinemiyor.
|
deleteCurrentUserMessage=Şu anda oturum açmış olan kullanıcı silinemiyor.
|
||||||
deleteUsernameExistsMessage=Kullanıcı adı mevcut değil ve silinemez.
|
deleteUsernameExistsMessage=Kullanıcı adı mevcut değil ve silinemez.
|
||||||
downgradeCurrentUserMessage=Mevcut kullanıcının rolü düşürülemiyor
|
downgradeCurrentUserMessage=Mevcut kullanıcının rolü düşürülemiyor
|
||||||
@@ -86,7 +86,7 @@ pipeline.defaultOption=Özel
|
|||||||
pipeline.submitButton=Gönder
|
pipeline.submitButton=Gönder
|
||||||
pipeline.help=Çoklu İşlemler Yardım
|
pipeline.help=Çoklu İşlemler Yardım
|
||||||
pipeline.scanHelp=Klasör Tarama Yardımı
|
pipeline.scanHelp=Klasör Tarama Yardımı
|
||||||
pipeline.deletePrompt=Çoklu işlemleri silmek istediğinizden emin misiniz
|
pipeline.deletePrompt=Are you sure you want to delete pipeline
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# Pipeline Options #
|
# Pipeline Options #
|
||||||
@@ -116,7 +116,7 @@ navbar.multiTool=Çoklu Araçlar
|
|||||||
navbar.sections.organize=Düzenle
|
navbar.sections.organize=Düzenle
|
||||||
navbar.sections.convertTo=PDF'ye dönüştür
|
navbar.sections.convertTo=PDF'ye dönüştür
|
||||||
navbar.sections.convertFrom=PDF'den dönüştür
|
navbar.sections.convertFrom=PDF'den dönüştür
|
||||||
navbar.sections.security=Oturum ve Güvenlik
|
navbar.sections.security=Oturum & Güvenlik
|
||||||
navbar.sections.advance=Gelişmiş
|
navbar.sections.advance=Gelişmiş
|
||||||
navbar.sections.edit=Görüntüle ve Düzenle
|
navbar.sections.edit=Görüntüle ve Düzenle
|
||||||
|
|
||||||
@@ -175,8 +175,8 @@ adminUserSettings.header=Yönetici Kullanıcı Kontrol Ayarları
|
|||||||
adminUserSettings.admin=Yönetici
|
adminUserSettings.admin=Yönetici
|
||||||
adminUserSettings.user=Kullanıcı
|
adminUserSettings.user=Kullanıcı
|
||||||
adminUserSettings.addUser=Yeni Kullanıcı Ekle
|
adminUserSettings.addUser=Yeni Kullanıcı Ekle
|
||||||
adminUserSettings.deleteUser=Kullanıcı Sil
|
adminUserSettings.deleteUser=Delete User
|
||||||
adminUserSettings.confirmDeleteUser=Kullanıcı silinsin mi?
|
adminUserSettings.confirmDeleteUser=Should the user be deleted?
|
||||||
adminUserSettings.usernameInfo=Kullanıcı adı yalnızca harf, rakam ve aşağıdaki özel karakterleri @._+- içerebilir veya geçerli bir e-posta adresi olmalıdır.
|
adminUserSettings.usernameInfo=Kullanıcı adı yalnızca harf, rakam ve aşağıdaki özel karakterleri @._+- içerebilir veya geçerli bir e-posta adresi olmalıdır.
|
||||||
adminUserSettings.roles=Roller
|
adminUserSettings.roles=Roller
|
||||||
adminUserSettings.role=Rol
|
adminUserSettings.role=Rol
|
||||||
@@ -192,21 +192,21 @@ adminUserSettings.changeUserRole=Kullanıcı rolünü değiştir
|
|||||||
adminUserSettings.authenticated=Onaylandı
|
adminUserSettings.authenticated=Onaylandı
|
||||||
|
|
||||||
|
|
||||||
database.title=Veri Tabanını İçe/Dışa Aktar
|
database.title=Database Import/Export
|
||||||
database.header=Veri Tabanını İçe/Dışa Aktar
|
database.header=Database Import/Export
|
||||||
database.fileName=Dosya Adı
|
database.fileName=File Name
|
||||||
database.creationDate=Oluşturulma Tarihi
|
database.creationDate=Creation Date
|
||||||
database.fileSize=Dosya Boyutu
|
database.fileSize=File Size
|
||||||
database.deleteBackupFile=Yedekleme Dosyasını Sil
|
database.deleteBackupFile=Delete Backup File
|
||||||
database.importBackupFile=Yedekleme Dosyasını İçe Aktar
|
database.importBackupFile=Import Backup File
|
||||||
database.downloadBackupFile=Yedekleme Dosyasını İndir
|
database.downloadBackupFile=Download Backup File
|
||||||
database.info_1=Verileri içe aktarırken, yapının doğru olduğundan emin olmak çok önemlidir. Ne yaptığınızdan emin değilseniz, bir uzmandan tavsiye ve destek alın. Yapıdaki bir hata, uygulamanın tamamen çalıştırılamaması da dahil olmak üzere uygulama sorunlarına neden olabilir.
|
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
|
||||||
database.info_2=Karşıya yüklerken dosya adı önemli değildir. Daha sonra yedekleme_kullanıcısı_yyyyAAggSdd.sql biçiminde yeniden adlandırılacak ve tutarlı bir adlandırma kuralı sağlanacaktır.
|
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
|
||||||
database.submit=Yedeklemeyi İçe Aktar
|
database.submit=Import Backup
|
||||||
database.importIntoDatabaseSuccessed=Veri tabanına başarıyla aktarıldı
|
database.importIntoDatabaseSuccessed=Import into database successed
|
||||||
database.fileNotFound=Dosya bulunamadı
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=Dosya yok veya boş olmamalıdır
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=Dosya İçe Aktarılamadı
|
database.failedImportFile=Failed Import File
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# HOME-PAGE #
|
# HOME-PAGE #
|
||||||
@@ -353,9 +353,9 @@ home.certSign.title=Sertifika ile İmzala
|
|||||||
home.certSign.desc=Bir PDF'i Sertifika/Anahtar (PEM/P12) ile imzalar
|
home.certSign.desc=Bir PDF'i Sertifika/Anahtar (PEM/P12) ile imzalar
|
||||||
certSign.tags=doğrula,PEM,P12,resmi,şifrele
|
certSign.tags=doğrula,PEM,P12,resmi,şifrele
|
||||||
|
|
||||||
home.removeCertSign.title=Sertifika İmzasını Kaldır
|
home.removeCertSign.title=Remove Certificate Sign
|
||||||
home.removeCertSign.desc=PDF'ten sertifika imzasını kaldırır
|
home.removeCertSign.desc=Remove certificate signature from PDF
|
||||||
removeCertSign.tags=doğrula,PEM,P12,resmi,şifre çöz
|
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
|
||||||
|
|
||||||
home.pageLayout.title=Çoklu-Sayfa Düzeni
|
home.pageLayout.title=Çoklu-Sayfa Düzeni
|
||||||
home.pageLayout.desc=Bir PDF belgesinin çoklu sayfalarını tek bir sayfada birleştirir
|
home.pageLayout.desc=Bir PDF belgesinin çoklu sayfalarını tek bir sayfada birleştirir
|
||||||
@@ -477,12 +477,12 @@ login.locked=Hesabınız kilitlendi.
|
|||||||
login.signinTitle=Lütfen giriş yapınız.
|
login.signinTitle=Lütfen giriş yapınız.
|
||||||
login.ssoSignIn=Tek Oturum Açma ile Giriş Yap
|
login.ssoSignIn=Tek Oturum Açma ile Giriş Yap
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Otomatik Oluşturma Kullanıcı Devre Dışı Bırakıldı
|
login.oauth2AutoCreateDisabled=OAUTH2 Otomatik Oluşturma Kullanıcı Devre Dışı Bırakıldı
|
||||||
login.oauth2RequestNotFound=Yetkilendirme isteği bulunamadı
|
login.oauth2RequestNotFound=Authorization request not found
|
||||||
login.oauth2InvalidUserInfoResponse=Geçersiz Kullanıcı Bilgisi Yanıtı
|
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
||||||
login.oauth2invalidRequest=Geçersiz İstek
|
login.oauth2invalidRequest=Invalid Request
|
||||||
login.oauth2AccessDenied=Erişim Reddedildi
|
login.oauth2AccessDenied=Access Denied
|
||||||
login.oauth2InvalidTokenResponse=Geçersiz Belirteç Yanıtı
|
login.oauth2InvalidTokenResponse=Invalid Token Response
|
||||||
login.oauth2InvalidIdToken=Geçersiz Kimlik Belirteci
|
login.oauth2InvalidIdToken=Invalid Id Token
|
||||||
|
|
||||||
|
|
||||||
#auto-redact
|
#auto-redact
|
||||||
@@ -681,10 +681,10 @@ certSign.submit=PDF'i İmzala
|
|||||||
|
|
||||||
|
|
||||||
#removeCertSign
|
#removeCertSign
|
||||||
removeCertSign.title=Sertifika İmzasını Kaldır
|
removeCertSign.title=Remove Certificate Signature
|
||||||
removeCertSign.header=PDF'ten dijital sertifikayı kaldırın
|
removeCertSign.header=Remove the digital certificate from the PDF
|
||||||
removeCertSign.selectPDF=PDF dosyası seçin:
|
removeCertSign.selectPDF=Select a PDF file:
|
||||||
removeCertSign.submit=İmzayı Kaldır
|
removeCertSign.submit=Remove Signature
|
||||||
|
|
||||||
|
|
||||||
#removeBlanks
|
#removeBlanks
|
||||||
@@ -706,8 +706,8 @@ removeAnnotations.submit=Kaldır
|
|||||||
#compare
|
#compare
|
||||||
compare.title=Karşılaştır
|
compare.title=Karşılaştır
|
||||||
compare.header=PDF'leri Karşılaştır
|
compare.header=PDF'leri Karşılaştır
|
||||||
compare.highlightColor.1=Vurgu Rengi 1:
|
compare.highlightColor.1=Highlight Color 1:
|
||||||
compare.highlightColor.2=Vurgu Rengi 2:
|
compare.highlightColor.2=Highlight Color 2:
|
||||||
compare.document.1=Belge 1
|
compare.document.1=Belge 1
|
||||||
compare.document.2=Belge 2
|
compare.document.2=Belge 2
|
||||||
compare.submit=Karşılaştır
|
compare.submit=Karşılaştır
|
||||||
@@ -744,7 +744,7 @@ repair.submit=Onar
|
|||||||
#flatten
|
#flatten
|
||||||
flatten.title=Düzleştir
|
flatten.title=Düzleştir
|
||||||
flatten.header=PDF'leri Düzleştir
|
flatten.header=PDF'leri Düzleştir
|
||||||
flatten.flattenOnlyForms=Yalnızca formları düzleştir
|
flatten.flattenOnlyForms=Flatten only forms
|
||||||
flatten.submit=Düzleştir
|
flatten.submit=Düzleştir
|
||||||
|
|
||||||
|
|
||||||
@@ -822,7 +822,7 @@ merge.title=Birleştir
|
|||||||
merge.header=Çoklu PDF'leri Birleştir (2+)
|
merge.header=Çoklu PDF'leri Birleştir (2+)
|
||||||
merge.sortByName=İsme göre sırala
|
merge.sortByName=İsme göre sırala
|
||||||
merge.sortByDate=Tarihe göre sırala
|
merge.sortByDate=Tarihe göre sırala
|
||||||
merge.removeCertSign=Birleştirilen dosyadaki dijital imza kaldırılsın mı?
|
merge.removeCertSign=Remove digital signature in the merged file?
|
||||||
merge.submit=Birleştir
|
merge.submit=Birleştir
|
||||||
|
|
||||||
|
|
||||||
@@ -840,7 +840,7 @@ pdfOrganiser.mode.6=Tek-Çift Ayrımı
|
|||||||
pdfOrganiser.mode.7=İlk Önce Kaldır
|
pdfOrganiser.mode.7=İlk Önce Kaldır
|
||||||
pdfOrganiser.mode.8=Sonuncuyu Kaldır
|
pdfOrganiser.mode.8=Sonuncuyu Kaldır
|
||||||
pdfOrganiser.mode.9=İlk ve Sonu Kaldır
|
pdfOrganiser.mode.9=İlk ve Sonu Kaldır
|
||||||
pdfOrganiser.mode.10=Tek-Çift Birleştirme
|
pdfOrganiser.mode.10=Odd-Even Merge
|
||||||
pdfOrganiser.placeholder=(örn. 1,3,2 veya 4-8,2,10-12 veya 2n-1)
|
pdfOrganiser.placeholder=(örn. 1,3,2 veya 4-8,2,10-12 veya 2n-1)
|
||||||
|
|
||||||
|
|
||||||
@@ -1099,17 +1099,17 @@ licenses.nav=Lisanslar
|
|||||||
licenses.title=3. Taraf Lisansları
|
licenses.title=3. Taraf Lisansları
|
||||||
licenses.header=3. Taraf Lisansları
|
licenses.header=3. Taraf Lisansları
|
||||||
licenses.module=Modül
|
licenses.module=Modül
|
||||||
licenses.version=Sürüm
|
licenses.version=Versiyon
|
||||||
licenses.license=Lisans
|
licenses.license=Lisans
|
||||||
|
|
||||||
#survey
|
#survey
|
||||||
survey.nav=Anket
|
survey.nav=Survey
|
||||||
survey.title=Stirling-PDF Anketi
|
survey.title=Stirling-PDF Survey
|
||||||
survey.description=Stirling-PDF'te izleme yok, bu yüzden Stirling-PDF'i iyileştirmek için kullanıcılarımızdan geri bildirim almak istiyoruz!
|
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
|
||||||
survey.please=Lütfen anketimize katılmayı düşünün!
|
survey.please=Please consider taking our survey!
|
||||||
survey.disabled=(Anket açılır penceresi sonraki güncellemelerde devre dışı bırakılacak ancak sayfanın alt kısmında yer alacaktır)
|
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
|
||||||
survey.button=Ankete Katıl
|
survey.button=Take Survey
|
||||||
survey.dontShowAgain=Tekrar gösterme
|
survey.dontShowAgain=Don't show again
|
||||||
|
|
||||||
|
|
||||||
#error
|
#error
|
||||||
@@ -1124,3 +1124,4 @@ error.showStack=Yığın İzlemesini Göster
|
|||||||
error.copyStack=Yığın İzini Kopyala
|
error.copyStack=Yığın İzini Kopyala
|
||||||
error.githubSubmit=GitHub - Hata gönderin
|
error.githubSubmit=GitHub - Hata gönderin
|
||||||
error.discordSubmit=Discord - Destek gönderisi gönderin
|
error.discordSubmit=Discord - Destek gönderisi gönderin
|
||||||
|
|
||||||
|
|||||||
@@ -1124,3 +1124,4 @@ error.showStack=Показати стек викликів
|
|||||||
error.copyStack=Скопіювати стек викликів
|
error.copyStack=Скопіювати стек викликів
|
||||||
error.githubSubmit=GitHub - Надіслати запит
|
error.githubSubmit=GitHub - Надіслати запит
|
||||||
error.discordSubmit=Discord - Надіслати повідомлення підтримки
|
error.discordSubmit=Discord - Надіслати повідомлення підтримки
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -192,21 +192,21 @@ adminUserSettings.changeUserRole=更改用户角色
|
|||||||
adminUserSettings.authenticated=已验证
|
adminUserSettings.authenticated=已验证
|
||||||
|
|
||||||
|
|
||||||
database.title=数据库 导入/导出
|
database.title=Database Import/Export
|
||||||
database.header=数据库 导入/导出
|
database.header=Database Import/Export
|
||||||
database.fileName=文件名
|
database.fileName=File Name
|
||||||
database.creationDate=创建时间
|
database.creationDate=Creation Date
|
||||||
database.fileSize=文件大小
|
database.fileSize=File Size
|
||||||
database.deleteBackupFile=删除备份文件
|
database.deleteBackupFile=Delete Backup File
|
||||||
database.importBackupFile=导入备份文件
|
database.importBackupFile=Import Backup File
|
||||||
database.downloadBackupFile=下载备份文件
|
database.downloadBackupFile=Download Backup File
|
||||||
database.info_1=导入数据时,确保结构正确至关重要。如果您不确定自己在做什么,请寻求专业人士的建议和支持。结构错误会导致应用程序故障,甚至完全无法运行应用程序。
|
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
|
||||||
database.info_2=上传文件时,文件名并不重要。上传后,文件名将重命名为 backup_user_yyyyMMddHHmm.sql,以确保命名规范的一致性。
|
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
|
||||||
database.submit=导入备份
|
database.submit=Import Backup
|
||||||
database.importIntoDatabaseSuccessed=导入数据库成功
|
database.importIntoDatabaseSuccessed=Import into database successed
|
||||||
database.fileNotFound=未找到文件
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=文件不能为空
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=导入文件失败
|
database.failedImportFile=Failed Import File
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# HOME-PAGE #
|
# HOME-PAGE #
|
||||||
@@ -1124,3 +1124,4 @@ error.showStack=显示堆栈跟踪
|
|||||||
error.copyStack=复制堆栈跟踪
|
error.copyStack=复制堆栈跟踪
|
||||||
error.githubSubmit=GitHub - 提交工单
|
error.githubSubmit=GitHub - 提交工单
|
||||||
error.discordSubmit=Discord - 提交支持帖子
|
error.discordSubmit=Discord - 提交支持帖子
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ multiPdfPrompt=選擇多個 PDF 檔案
|
|||||||
multiPdfDropPrompt=選擇(或拖放)所有需要的 PDF 檔案
|
multiPdfDropPrompt=選擇(或拖放)所有需要的 PDF 檔案
|
||||||
imgPrompt=選擇圖片
|
imgPrompt=選擇圖片
|
||||||
genericSubmit=送出
|
genericSubmit=送出
|
||||||
processTimeWarning=警告:此過程可能長達一分鐘,具體取決於檔案大小
|
processTimeWarning=警告:此過程可能需要長達一分鐘,具體取決於檔案大小
|
||||||
pageOrderPrompt=自訂頁面順序(輸入以逗號分隔的頁碼或函式,如 2n+1):
|
pageOrderPrompt=自訂頁面順序(輸入以逗號分隔的頁碼或函式,如 2n+1):
|
||||||
pageSelectionPrompt=自訂頁面選擇(輸入以逗號分隔的頁碼 1、5、6 或 2n+1 等函數的清單):
|
pageSelectionPrompt=自訂頁面選擇(輸入以逗號分隔的頁碼 1、5、6 或 2n+1 等函數的清單):
|
||||||
goToPage=前往
|
goToPage=前往
|
||||||
@@ -66,7 +66,7 @@ error=錯誤
|
|||||||
oops=哎呀!
|
oops=哎呀!
|
||||||
help=幫助
|
help=幫助
|
||||||
goHomepage=前往首頁
|
goHomepage=前往首頁
|
||||||
joinDiscord=加入我們的 Discord 伺服器
|
joinDiscord=加入我們的 Discord 服務器
|
||||||
seeDockerHub=查看 Docker Hub
|
seeDockerHub=查看 Docker Hub
|
||||||
visitGithub=訪問 GitHub 存儲庫
|
visitGithub=訪問 GitHub 存儲庫
|
||||||
donate=捐贈
|
donate=捐贈
|
||||||
@@ -108,7 +108,7 @@ pipelineOptions.validateButton=驗證
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=我的最愛
|
navbar.favorite=我的最愛
|
||||||
navbar.darkmode=深色模式
|
navbar.darkmode=暗黑模式
|
||||||
navbar.language=語言
|
navbar.language=語言
|
||||||
navbar.settings=設定
|
navbar.settings=設定
|
||||||
navbar.allTools=工具
|
navbar.allTools=工具
|
||||||
@@ -125,7 +125,7 @@ navbar.sections.edit=檢視與編輯
|
|||||||
#############
|
#############
|
||||||
settings.title=設定
|
settings.title=設定
|
||||||
settings.update=有更新可用
|
settings.update=有更新可用
|
||||||
settings.updateAvailable=當前版本為 {0}。歡迎你更新至最新版 ({1})。。
|
settings.updateAvailable=當前版本為 {0}。歡迎您更新至最新版 ({1})。。
|
||||||
settings.appVersion=應用版本:
|
settings.appVersion=應用版本:
|
||||||
settings.downloadOption.title=選擇下載選項(對於單一檔案非壓縮下載):
|
settings.downloadOption.title=選擇下載選項(對於單一檔案非壓縮下載):
|
||||||
settings.downloadOption.1=在同一視窗中開啟
|
settings.downloadOption.1=在同一視窗中開啟
|
||||||
@@ -139,8 +139,8 @@ settings.cacheInputs.name=輸入檔案下載
|
|||||||
settings.cacheInputs.help=開啟記住先前的輸入,做為日後使用
|
settings.cacheInputs.help=開啟記住先前的輸入,做為日後使用
|
||||||
|
|
||||||
changeCreds.title=變更憑證
|
changeCreds.title=變更憑證
|
||||||
changeCreds.header=更新你的帳戶詳細資訊
|
changeCreds.header=更新您的帳戶詳細資訊
|
||||||
changeCreds.changePassword=你使用的是預設登錄認證。請輸入新密碼
|
changeCreds.changePassword=您使用的是預設登錄認證。請輸入新密碼
|
||||||
changeCreds.newUsername=新使用者名稱
|
changeCreds.newUsername=新使用者名稱
|
||||||
changeCreds.oldPassword=目前密碼
|
changeCreds.oldPassword=目前密碼
|
||||||
changeCreds.newPassword=新密碼
|
changeCreds.newPassword=新密碼
|
||||||
@@ -161,7 +161,7 @@ account.newPassword=新密碼
|
|||||||
account.changePassword=修改密碼
|
account.changePassword=修改密碼
|
||||||
account.confirmNewPassword=確認新密碼
|
account.confirmNewPassword=確認新密碼
|
||||||
account.signOut=登出
|
account.signOut=登出
|
||||||
account.yourApiKey=你的 API 金鑰
|
account.yourApiKey=您的 API 金鑰
|
||||||
account.syncTitle=將瀏覽器設定與帳戶同步
|
account.syncTitle=將瀏覽器設定與帳戶同步
|
||||||
account.settingsCompare=設定比較:
|
account.settingsCompare=設定比較:
|
||||||
account.property=屬性
|
account.property=屬性
|
||||||
@@ -192,26 +192,26 @@ adminUserSettings.changeUserRole=更改使用者身份
|
|||||||
adminUserSettings.authenticated=已驗證
|
adminUserSettings.authenticated=已驗證
|
||||||
|
|
||||||
|
|
||||||
database.title=資料庫匯入/匯出
|
database.title=Database Import/Export
|
||||||
database.header=資料庫匯入/匯出
|
database.header=Database Import/Export
|
||||||
database.fileName=檔案名稱
|
database.fileName=File Name
|
||||||
database.creationDate=建立日期
|
database.creationDate=Creation Date
|
||||||
database.fileSize=檔案大小
|
database.fileSize=File Size
|
||||||
database.deleteBackupFile=刪除備份檔案
|
database.deleteBackupFile=Delete Backup File
|
||||||
database.importBackupFile=匯入備份檔案
|
database.importBackupFile=Import Backup File
|
||||||
database.downloadBackupFile=下載備份檔案
|
database.downloadBackupFile=Download Backup File
|
||||||
database.info_1=在匯入資料時,確保正確的結構是至關重要的。如果你不確定自己在做什麼,請尋求專業人士的建議和支持。結構錯誤可能會導致應用程式故障,甚至完全無法運行。
|
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
|
||||||
database.info_2=上傳時檔案名稱無關緊要。上傳後將重新命名為 backup_user_yyyyMMddHHmm.sql 格式,以確保命名規範一致。
|
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
|
||||||
database.submit=匯入備份
|
database.submit=Import Backup
|
||||||
database.importIntoDatabaseSuccessed=成功匯入資料庫
|
database.importIntoDatabaseSuccessed=Import into database successed
|
||||||
database.fileNotFound=檔案未找到
|
database.fileNotFound=File not Found
|
||||||
database.fileNullOrEmpty=檔案不能為空或空白
|
database.fileNullOrEmpty=File must not be null or empty
|
||||||
database.failedImportFile=匯入檔案失敗
|
database.failedImportFile=Failed Import File
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# HOME-PAGE #
|
# HOME-PAGE #
|
||||||
#############
|
#############
|
||||||
home.desc=你的本地主機一站式 PDF 需求解決方案。
|
home.desc=您的本地主機一站式 PDF 需求解決方案。
|
||||||
home.searchBar=搜尋功能...
|
home.searchBar=搜尋功能...
|
||||||
|
|
||||||
|
|
||||||
@@ -232,7 +232,7 @@ home.split.desc=將 PDF 分割為多個文件
|
|||||||
split.tags=頁面操作,劃分,多頁,剪下,伺服器端
|
split.tags=頁面操作,劃分,多頁,剪下,伺服器端
|
||||||
|
|
||||||
home.rotate.title=旋轉
|
home.rotate.title=旋轉
|
||||||
home.rotate.desc=輕鬆旋轉你的 PDF。
|
home.rotate.desc=輕鬆旋轉您的 PDF。
|
||||||
rotate.tags=伺服器端
|
rotate.tags=伺服器端
|
||||||
|
|
||||||
|
|
||||||
@@ -254,24 +254,24 @@ home.addImage.desc=在 PDF 的指定位置新增圖片
|
|||||||
addImage.tags=img,jpg,圖片,照片
|
addImage.tags=img,jpg,圖片,照片
|
||||||
|
|
||||||
home.watermark.title=新增浮水印
|
home.watermark.title=新增浮水印
|
||||||
home.watermark.desc=在你的 PDF 檔案中新增自訂浮水印。
|
home.watermark.desc=在您的 PDF 檔案中新增自訂浮水印。
|
||||||
watermark.tags=文字,重複,標籤,自有,版權,商標,img,jpg,圖片,照片
|
watermark.tags=文字,重複,標籤,自有,版權,商標,img,jpg,圖片,照片
|
||||||
|
|
||||||
home.permissions.title=修改權限
|
home.permissions.title=修改權限
|
||||||
home.permissions.desc=修改你的 PDF 檔案權限
|
home.permissions.desc=修改您的 PDF 檔案權限
|
||||||
permissions.tags=讀取,寫入,編輯,列印
|
permissions.tags=讀取,寫入,編輯,列印
|
||||||
|
|
||||||
|
|
||||||
home.removePages.title=移除
|
home.removePages.title=移除
|
||||||
home.removePages.desc=從你的 PDF 檔案中刪除不需要的頁面。
|
home.removePages.desc=從您的 PDF 檔案中刪除不需要的頁面。
|
||||||
removePages.tags=移除頁面,刪除頁面
|
removePages.tags=移除頁面,刪除頁面
|
||||||
|
|
||||||
home.addPassword.title=新增密碼
|
home.addPassword.title=新增密碼
|
||||||
home.addPassword.desc=用密碼加密你的 PDF 檔案。
|
home.addPassword.desc=用密碼加密您的 PDF 檔案。
|
||||||
addPassword.tags=安全,安全性
|
addPassword.tags=安全,安全性
|
||||||
|
|
||||||
home.removePassword.title=移除密碼
|
home.removePassword.title=移除密碼
|
||||||
home.removePassword.desc=從你的 PDF 檔案中移除密碼保護。
|
home.removePassword.desc=從您的 PDF 檔案中移除密碼保護。
|
||||||
removePassword.tags=安全,解密,安全性,取消密碼,刪除密碼
|
removePassword.tags=安全,解密,安全性,取消密碼,刪除密碼
|
||||||
|
|
||||||
home.compressPdfs.title=壓縮
|
home.compressPdfs.title=壓縮
|
||||||
@@ -473,7 +473,7 @@ login.header=登入
|
|||||||
login.signin=登入
|
login.signin=登入
|
||||||
login.rememberme=記住我
|
login.rememberme=記住我
|
||||||
login.invalid=使用者名稱或密碼無效。
|
login.invalid=使用者名稱或密碼無效。
|
||||||
login.locked=你的帳戶已被鎖定。
|
login.locked=您的帳戶已被鎖定。
|
||||||
login.signinTitle=請登入
|
login.signinTitle=請登入
|
||||||
login.ssoSignIn=透過織網單一簽入
|
login.ssoSignIn=透過織網單一簽入
|
||||||
login.oauth2AutoCreateDisabled=OAuth 2.0 自動建立使用者已停用
|
login.oauth2AutoCreateDisabled=OAuth 2.0 自動建立使用者已停用
|
||||||
@@ -664,15 +664,15 @@ scalePages.submit=送出
|
|||||||
|
|
||||||
#certSign
|
#certSign
|
||||||
certSign.title=憑證簽章
|
certSign.title=憑證簽章
|
||||||
certSign.header=使用你的憑證簽章(進行中)
|
certSign.header=使用您的憑證簽章(進行中)
|
||||||
certSign.selectPDF=選擇要簽章的 PDF 檔案:
|
certSign.selectPDF=選擇要簽章的 PDF 檔案:
|
||||||
certSign.jksNote=注意:如果你的證書類型未在下面列出,請使用 keytool 命令行工具將其轉換為 Java Keystore (.jks) 檔。 然後,選擇下面的 .jks 文件選項。
|
certSign.jksNote=注意:如果您的證書類型未在下面列出,請使用 keytool 命令行工具將其轉換為 Java Keystore (.jks) 檔。 然後,選擇下面的 .jks 文件選項。
|
||||||
certSign.selectKey=選擇你的私鑰文件(PKCS#8 格式,可能是 .pem 或 .der):
|
certSign.selectKey=選擇您的私鑰文件(PKCS#8 格式,可能是 .pem 或 .der):
|
||||||
certSign.selectCert=選擇你的憑證文件(X.509 格式,可能是 .pem 或 .der):
|
certSign.selectCert=選擇您的憑證文件(X.509 格式,可能是 .pem 或 .der):
|
||||||
certSign.selectP12=選擇你的 PKCS#12 金鑰庫文件(.p12 或 .pfx)(可選,如果提供,它應包含你的私鑰和憑證):
|
certSign.selectP12=選擇您的 PKCS#12 金鑰庫文件(.p12 或 .pfx)(可選,如果提供,它應包含您的私鑰和憑證):
|
||||||
certSign.selectJKS=選擇你的 Java Keystore 檔 (.jks 或 .keystore):
|
certSign.selectJKS=選擇你的 Java Keystore 檔 (.jks 或 .keystore):
|
||||||
certSign.certType=憑證類型
|
certSign.certType=憑證類型
|
||||||
certSign.password=輸入你的金鑰庫或私鑰密碼(如果有):
|
certSign.password=輸入您的金鑰庫或私鑰密碼(如果有):
|
||||||
certSign.showSig=顯示簽章
|
certSign.showSig=顯示簽章
|
||||||
certSign.reason=原因
|
certSign.reason=原因
|
||||||
certSign.location=位置
|
certSign.location=位置
|
||||||
@@ -871,7 +871,7 @@ rotate.submit=旋轉
|
|||||||
#split-pdfs
|
#split-pdfs
|
||||||
split.title=分割 PDF
|
split.title=分割 PDF
|
||||||
split.header=分割 PDF
|
split.header=分割 PDF
|
||||||
split.desc.1=你選擇的數字是你希望進行分割的頁碼
|
split.desc.1=您選擇的數字是您希望進行分割的頁碼
|
||||||
split.desc.2=因此,選擇 1,3,7-9 將會將一個 10 頁的文件分割為 6 個單獨的 PDF,包括:
|
split.desc.2=因此,選擇 1,3,7-9 將會將一個 10 頁的文件分割為 6 個單獨的 PDF,包括:
|
||||||
split.desc.3=文件 #1:頁面 1
|
split.desc.3=文件 #1:頁面 1
|
||||||
split.desc.4=文件 #2:頁面 2 和 3
|
split.desc.4=文件 #2:頁面 2 和 3
|
||||||
@@ -978,7 +978,7 @@ removePassword.submit=移除
|
|||||||
#changeMetadata
|
#changeMetadata
|
||||||
changeMetadata.title=標題:
|
changeMetadata.title=標題:
|
||||||
changeMetadata.header=變更中繼資料
|
changeMetadata.header=變更中繼資料
|
||||||
changeMetadata.selectText.1=請編輯你希望變更的變數
|
changeMetadata.selectText.1=請編輯您希望變更的變數
|
||||||
changeMetadata.selectText.2=刪除所有中繼資料
|
changeMetadata.selectText.2=刪除所有中繼資料
|
||||||
changeMetadata.selectText.3=顯示自訂中繼資料:
|
changeMetadata.selectText.3=顯示自訂中繼資料:
|
||||||
changeMetadata.author=作者:
|
changeMetadata.author=作者:
|
||||||
@@ -1103,13 +1103,13 @@ licenses.version=版本
|
|||||||
licenses.license=許可證
|
licenses.license=許可證
|
||||||
|
|
||||||
#survey
|
#survey
|
||||||
survey.nav=問卷調查
|
survey.nav=Survey
|
||||||
survey.title=Stirling-PDF 問卷調查
|
survey.title=Stirling-PDF Survey
|
||||||
survey.description=Stirling-PDF 沒有追蹤功能,所以我們希望聽取用戶的意見來改進 Stirling-PDF!
|
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
|
||||||
survey.please=請考慮參加我們的問卷調查!
|
survey.please=Please consider taking our survey!
|
||||||
survey.disabled=(問卷調查彈出窗口將在後續更新中停用,但仍可在頁腳處使用)
|
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
|
||||||
survey.button=參加問卷調查
|
survey.button=Take Survey
|
||||||
survey.dontShowAgain=不要再次顯示
|
survey.dontShowAgain=Don't show again
|
||||||
|
|
||||||
|
|
||||||
#error
|
#error
|
||||||
@@ -1124,3 +1124,4 @@ error.showStack=顯示堆疊追蹤
|
|||||||
error.copyStack=複製堆疊追蹤
|
error.copyStack=複製堆疊追蹤
|
||||||
error.githubSubmit=GitHub - 提交工單
|
error.githubSubmit=GitHub - 提交工單
|
||||||
error.discordSubmit=Discord - 提交支援帖子
|
error.discordSubmit=Discord - 提交支援帖子
|
||||||
|
|
||||||
|
|||||||
@@ -906,7 +906,7 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-devtools",
|
"moduleName": "org.springframework.boot:spring-boot-devtools",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.3.2",
|
"moduleVersion": "3.3.0",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
@@ -920,7 +920,7 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-actuator",
|
"moduleName": "org.springframework.boot:spring-boot-starter-actuator",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.3.2",
|
"moduleVersion": "3.3.0",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
@@ -934,7 +934,7 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-data-jpa",
|
"moduleName": "org.springframework.boot:spring-boot-starter-data-jpa",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.3.2",
|
"moduleVersion": "3.3.0",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
@@ -948,7 +948,7 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-jetty",
|
"moduleName": "org.springframework.boot:spring-boot-starter-jetty",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.3.2",
|
"moduleVersion": "3.3.0",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
@@ -969,28 +969,28 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-oauth2-client",
|
"moduleName": "org.springframework.boot:spring-boot-starter-oauth2-client",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.3.2",
|
"moduleVersion": "3.3.0",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-security",
|
"moduleName": "org.springframework.boot:spring-boot-starter-security",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.3.2",
|
"moduleVersion": "3.3.0",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-thymeleaf",
|
"moduleName": "org.springframework.boot:spring-boot-starter-thymeleaf",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.3.2",
|
"moduleVersion": "3.3.0",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-web",
|
"moduleName": "org.springframework.boot:spring-boot-starter-web",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.3.2",
|
"moduleVersion": "3.3.0",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,22 +25,4 @@
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
left: 0;
|
left: 0;
|
||||||
transform-origin: center center;
|
|
||||||
}
|
|
||||||
.rotate-handle {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
background: blue;
|
|
||||||
position: absolute;
|
|
||||||
top: -20px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.rotate-button {
|
|
||||||
background-color: rgba(13, 110, 253, 0.1);
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 5px;
|
|
||||||
margin: 2px;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,22 +36,4 @@ select#font-select option {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
left: 0;
|
left: 0;
|
||||||
transform-origin: center center;
|
|
||||||
}
|
|
||||||
.rotate-handle {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
background: blue;
|
|
||||||
position: absolute;
|
|
||||||
top: -20px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.rotate-button {
|
|
||||||
background-color: rgba(13, 110, 253, 0.1);
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 5px;
|
|
||||||
margin: 2px;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-dk" viewBox="0 0 640 480">
|
|
||||||
<path fill="#c8102e" d="M0 0h640.1v480H0z"/>
|
|
||||||
<path fill="#fff" d="M205.7 0h68.6v480h-68.6z"/>
|
|
||||||
<path fill="#fff" d="M0 205.7h640.1v68.6H0z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 236 B |
@@ -1,7 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-ie" viewBox="0 0 640 480">
|
|
||||||
<g fill-rule="evenodd" stroke-width="1pt">
|
|
||||||
<path fill="#fff" d="M0 0h640v480H0z"/>
|
|
||||||
<path fill="#009A49" d="M0 0h213.3v480H0z"/>
|
|
||||||
<path fill="#FF7900" d="M426.7 0H640v480H426.7z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 289 B |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 600"><g fill-rule="evenodd" stroke-width="1pt"><path fill="#a51931" d="M0 0h900v600H0z"/><path fill="#fff" d="M0 120h900v360H0z"/><path fill="#241d4f" d="M0 240h900v120H0z"/></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 241 B |
@@ -1,11 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-vn" viewBox="0 0 640 480">
|
|
||||||
<defs>
|
|
||||||
<clipPath id="vn-a">
|
|
||||||
<path fill-opacity=".7" d="M-85.3 0h682.6v512H-85.3z"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
<g fill-rule="evenodd" clip-path="url(#vn-a)" transform="translate(80)scale(.9375)">
|
|
||||||
<path fill="#da251d" d="M-128 0h768v512h-768z"/>
|
|
||||||
<path fill="#ff0" d="M349.6 381 260 314.3l-89 67.3L204 272l-89-67.7 110.1-1 34.2-109.4L294 203l110.1.1-88.5 68.4 33.9 109.6z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 490 B |
@@ -12,7 +12,7 @@ $(document).ready(function () {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
firstErrorOccurred = false;
|
firstErrorOccurred = false;
|
||||||
const url = this.action;
|
const url = this.action;
|
||||||
const files = $("#fileInput-input")[0].files;
|
var files = $("#fileInput-input")[0].files;
|
||||||
const formData = new FormData(this);
|
const formData = new FormData(this);
|
||||||
|
|
||||||
// Remove empty file entries
|
// Remove empty file entries
|
||||||
@@ -36,6 +36,17 @@ $(document).ready(function () {
|
|||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
if (!url.includes("remove-password")) {
|
||||||
|
// Check if any PDF files are encrypted and handle decryption if necessary
|
||||||
|
const decryptedFiles = await checkAndDecryptFiles(url ,files);
|
||||||
|
files = decryptedFiles
|
||||||
|
// Append decrypted files to formData
|
||||||
|
decryptedFiles.forEach((file, index) => {
|
||||||
|
formData.set(`fileInput`, file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (remoteCall === true) {
|
if (remoteCall === true) {
|
||||||
if (override === "multi" || (!multiple && files.length > 1 && override !== "single")) {
|
if (override === "multi" || (!multiple && files.length > 1 && override !== "single")) {
|
||||||
await submitMultiPdfForm(url, files);
|
await submitMultiPdfForm(url, files);
|
||||||
@@ -72,6 +83,97 @@ $(document).ready(function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function checkAndDecryptFiles(url, files) {
|
||||||
|
const decryptedFiles = [];
|
||||||
|
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
|
||||||
|
|
||||||
|
// Extract the base URL
|
||||||
|
const baseUrl = new URL(url);
|
||||||
|
let removePasswordUrl = `${baseUrl.origin}`;
|
||||||
|
|
||||||
|
// Check if there's a path before /api/
|
||||||
|
const apiIndex = baseUrl.pathname.indexOf('/api/');
|
||||||
|
if (apiIndex > 0) {
|
||||||
|
removePasswordUrl += baseUrl.pathname.substring(0, apiIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the new endpoint
|
||||||
|
removePasswordUrl += '/api/v1/security/remove-password';
|
||||||
|
|
||||||
|
console.log(`Remove password URL: ${removePasswordUrl}`);
|
||||||
|
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
console.log(`Processing file: ${file.name}`);
|
||||||
|
if (file.type !== 'application/pdf') {
|
||||||
|
console.log(`Skipping non-PDF file: ${file.name}`);
|
||||||
|
decryptedFiles.push(file);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const arrayBuffer = await file.arrayBuffer();
|
||||||
|
const loadingTask = pdfjsLib.getDocument({ data: arrayBuffer });
|
||||||
|
|
||||||
|
console.log(`Attempting to load PDF: ${file.name}`);
|
||||||
|
const pdf = await loadingTask.promise;
|
||||||
|
console.log(`File is not encrypted: ${file.name}`);
|
||||||
|
decryptedFiles.push(file); // If no error, file is not encrypted
|
||||||
|
} catch (error) {
|
||||||
|
if (error.name === 'PasswordException' && error.code === 1) {
|
||||||
|
console.log(`PDF requires password: ${file.name}`, error);
|
||||||
|
console.log(`Attempting to remove password from PDF: ${file.name} with password.`);
|
||||||
|
const password = prompt(`This PDF (${file.name}) is encrypted. Please enter the password:`);
|
||||||
|
|
||||||
|
if (!password) {
|
||||||
|
console.error(`No password provided for encrypted PDF: ${file.name}`);
|
||||||
|
showErrorBanner(`No password provided for encrypted PDF: ${file.name}`, 'Please enter a valid password.');
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Prepare FormData for the decryption request
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('fileInput', file);
|
||||||
|
formData.append('password', password);
|
||||||
|
|
||||||
|
// Use handleSingleDownload to send the request
|
||||||
|
const decryptionResult = await fetch(removePasswordUrl, { method: "POST", body: formData });
|
||||||
|
|
||||||
|
if (decryptionResult && decryptionResult.blob) {
|
||||||
|
const decryptedBlob = await decryptionResult.blob();
|
||||||
|
const decryptedFile = new File([decryptedBlob], file.name, { type: 'application/pdf' });
|
||||||
|
|
||||||
|
/* // Create a link element to download the file
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = URL.createObjectURL(decryptedBlob);
|
||||||
|
link.download = 'test.pdf';
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
*/
|
||||||
|
decryptedFiles.push(decryptedFile);
|
||||||
|
console.log(`Successfully decrypted PDF: ${file.name}`);
|
||||||
|
} else {
|
||||||
|
throw new Error('Decryption failed: No valid response from server');
|
||||||
|
}
|
||||||
|
} catch (decryptError) {
|
||||||
|
console.error(`Failed to decrypt PDF: ${file.name}`, decryptError);
|
||||||
|
showErrorBanner(`Failed to decrypt PDF: ${file.name}`, 'Incorrect password or unsupported encryption.');
|
||||||
|
throw decryptError;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(`Error loading PDF: ${file.name}`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return decryptedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function handleSingleDownload(url, formData, isMulti = false, isZip = false) {
|
async function handleSingleDownload(url, formData, isMulti = false, isZip = false) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url, { method: "POST", body: formData });
|
const response = await fetch(url, { method: "POST", body: formData });
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const DraggableUtils = {
|
|||||||
const y = (parseFloat(target.getAttribute("data-bs-y")) || 0)
|
const y = (parseFloat(target.getAttribute("data-bs-y")) || 0)
|
||||||
+ event.dy;
|
+ event.dy;
|
||||||
|
|
||||||
target.style.transform = `translate(${x}px, ${y}px) rotate(${target.getAttribute("data-rotation") || 0}deg)`;
|
target.style.transform = `translate(${x}px, ${y}px)`;
|
||||||
target.setAttribute("data-bs-x", x);
|
target.setAttribute("data-bs-x", x);
|
||||||
target.setAttribute("data-bs-y", y);
|
target.setAttribute("data-bs-y", y);
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ const DraggableUtils = {
|
|||||||
x += event.deltaRect.left;
|
x += event.deltaRect.left;
|
||||||
y += event.deltaRect.top;
|
y += event.deltaRect.top;
|
||||||
|
|
||||||
target.style.transform = `translate(${x}px, ${y}px) rotate(${target.getAttribute("data-rotation") || 0}deg)`;
|
target.style.transform = "translate(" + x + "px," + y + "px)";
|
||||||
|
|
||||||
target.setAttribute("data-bs-x", x);
|
target.setAttribute("data-bs-x", x);
|
||||||
target.setAttribute("data-bs-y", y);
|
target.setAttribute("data-bs-y", y);
|
||||||
@@ -78,17 +78,6 @@ const DraggableUtils = {
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
inertia: true,
|
inertia: true,
|
||||||
})
|
|
||||||
.gesturable({
|
|
||||||
listeners: {
|
|
||||||
move: (event) => {
|
|
||||||
const target = event.target;
|
|
||||||
const rotation = (parseFloat(target.getAttribute("data-rotation")) || 0) + event.da;
|
|
||||||
target.style.transform = `translate(${parseFloat(target.getAttribute("data-bs-x")) || 0}px, ${parseFloat(target.getAttribute("data-bs-y")) || 0}px) rotate(${rotation}deg)`;
|
|
||||||
target.setAttribute("data-rotation", rotation);
|
|
||||||
this.onInteraction(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
//Arrow key Support for Add-Image and Sign pages
|
//Arrow key Support for Add-Image and Sign pages
|
||||||
if(window.location.pathname.endsWith('sign') || window.location.pathname.endsWith('add-image')) {
|
if(window.location.pathname.endsWith('sign') || window.location.pathname.endsWith('add-image')) {
|
||||||
@@ -131,7 +120,7 @@ const DraggableUtils = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update position
|
// Update position
|
||||||
target.style.transform = `translate(${x}px, ${y}px) rotate(${target.getAttribute("data-rotation") || 0}deg)`;
|
target.style.transform = `translate(${x}px, ${y}px)`;
|
||||||
target.setAttribute('data-bs-x', x);
|
target.setAttribute('data-bs-x', x);
|
||||||
target.setAttribute('data-bs-y', y);
|
target.setAttribute('data-bs-y', y);
|
||||||
|
|
||||||
@@ -151,10 +140,9 @@ const DraggableUtils = {
|
|||||||
|
|
||||||
const x = 0;
|
const x = 0;
|
||||||
const y = 20;
|
const y = 20;
|
||||||
createdCanvas.style.transform = `translate(${x}px, ${y}px) rotate(0deg)`;
|
createdCanvas.style.transform = `translate(${x}px, ${y}px)`;
|
||||||
createdCanvas.setAttribute("data-bs-x", x);
|
createdCanvas.setAttribute("data-bs-x", x);
|
||||||
createdCanvas.setAttribute("data-bs-y", y);
|
createdCanvas.setAttribute("data-bs-y", y);
|
||||||
createdCanvas.setAttribute("data-rotation", 0);
|
|
||||||
|
|
||||||
//Click element in order to enable arrow keys
|
//Click element in order to enable arrow keys
|
||||||
createdCanvas.addEventListener('click', () => {
|
createdCanvas.addEventListener('click', () => {
|
||||||
@@ -235,7 +223,6 @@ const DraggableUtils = {
|
|||||||
element: el,
|
element: el,
|
||||||
offsetWidth: el.offsetWidth,
|
offsetWidth: el.offsetWidth,
|
||||||
offsetHeight: el.offsetHeight,
|
offsetHeight: el.offsetHeight,
|
||||||
rotation: el.getAttribute("data-rotation") || 0,
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
elements.forEach((el) => this.boxDragContainer.removeChild(el));
|
elements.forEach((el) => this.boxDragContainer.removeChild(el));
|
||||||
@@ -255,11 +242,7 @@ const DraggableUtils = {
|
|||||||
|
|
||||||
const draggablesData = pagesMap[this.pageIndex];
|
const draggablesData = pagesMap[this.pageIndex];
|
||||||
if (draggablesData) {
|
if (draggablesData) {
|
||||||
draggablesData.forEach((draggableData) => {
|
draggablesData.forEach((draggableData) => this.boxDragContainer.appendChild(draggableData.element));
|
||||||
const el = draggableData.element;
|
|
||||||
el.style.transform = `translate(${parseFloat(el.getAttribute("data-bs-x")) || 0}px, ${parseFloat(el.getAttribute("data-bs-y")) || 0}px) rotate(${draggableData.rotation}deg)`;
|
|
||||||
this.boxDragContainer.appendChild(el);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
this.documentsMap.set(this.pdfDoc, pagesMap);
|
||||||
@@ -340,7 +323,6 @@ const DraggableUtils = {
|
|||||||
y: parseFloat(transformComponents[1]),
|
y: parseFloat(transformComponents[1]),
|
||||||
width: draggableData.offsetWidth,
|
width: draggableData.offsetWidth,
|
||||||
height: draggableData.offsetHeight,
|
height: draggableData.offsetHeight,
|
||||||
rotation: parseFloat(draggableData.rotation),
|
|
||||||
};
|
};
|
||||||
const draggablePositionRelative = {
|
const draggablePositionRelative = {
|
||||||
x: draggablePositionPixels.x / offsetWidth,
|
x: draggablePositionPixels.x / offsetWidth,
|
||||||
@@ -353,7 +335,6 @@ const DraggableUtils = {
|
|||||||
y: draggablePositionRelative.y * page.getHeight(),
|
y: draggablePositionRelative.y * page.getHeight(),
|
||||||
width: draggablePositionRelative.width * page.getWidth(),
|
width: draggablePositionRelative.width * page.getWidth(),
|
||||||
height: draggablePositionRelative.height * page.getHeight(),
|
height: draggablePositionRelative.height * page.getHeight(),
|
||||||
rotation: draggablePositionPixels.rotation,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// draw the image
|
// draw the image
|
||||||
@@ -362,7 +343,6 @@ const DraggableUtils = {
|
|||||||
y: page.getHeight() - draggablePositionPdf.y - draggablePositionPdf.height,
|
y: page.getHeight() - draggablePositionPdf.y - draggablePositionPdf.height,
|
||||||
width: draggablePositionPdf.width,
|
width: draggablePositionPdf.width,
|
||||||
height: draggablePositionPdf.height,
|
height: draggablePositionPdf.height,
|
||||||
rotate: PDFLib.degrees(draggablePositionPdf.rotation),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -370,13 +350,6 @@ const DraggableUtils = {
|
|||||||
this.loadPageContents();
|
this.loadPageContents();
|
||||||
return pdfDocModified;
|
return pdfDocModified;
|
||||||
},
|
},
|
||||||
|
|
||||||
rotateElement(element, angle) {
|
|
||||||
const currentRotation = parseFloat(element.getAttribute("data-rotation")) || 0;
|
|
||||||
const newRotation = currentRotation + angle;
|
|
||||||
element.style.transform = `translate(${parseFloat(element.getAttribute("data-bs-x")) || 0}px, ${parseFloat(element.getAttribute("data-bs-y")) || 0}px) rotate(${newRotation}deg)`;
|
|
||||||
element.setAttribute("data-rotation", newRotation);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<p th:text="#{error.contactTip}"></p>
|
<p th:text="#{error.contactTip}"></p>
|
||||||
<div id="button-group">
|
<div id="button-group">
|
||||||
<a href="https://github.com/Stirling-Tools/Stirling-PDF/issues" id="github-button" class="btn btn-primary" target="_blank" th:text="#{error.github}"></a>
|
<a href="https://github.com/Stirling-Tools/Stirling-PDF/issues" id="github-button" class="btn btn-primary" target="_blank" th:text="#{error.github}"></a>
|
||||||
<a href="https://discord.gg/Cn8pWhQRxZ" id="discord-button" class="btn btn-primary" target="_blank" th:text="#{joinDiscord}"></a>
|
<a href="https://discord.gg/HYmhKj45pU" id="discord-button" class="btn btn-primary" target="_blank" th:text="#{joinDiscord}"></a>
|
||||||
</div>
|
</div>
|
||||||
<a th:href="@{'/'}" id="home-button" class="home-button btn btn-primary" th:text="#{goHomepage}"></a>
|
<a th:href="@{'/'}" id="home-button" class="home-button btn btn-primary" th:text="#{goHomepage}"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- Buttons to submit a ticket on GitHub and join Discord server -->
|
<!-- Buttons to submit a ticket on GitHub and join Discord server -->
|
||||||
<a href="https://github.com/Stirling-Tools/Stirling-PDF/issues" id="github-button" target="_blank" th:text="#{error.github}"></a>
|
<a href="https://github.com/Stirling-Tools/Stirling-PDF/issues" id="github-button" target="_blank" th:text="#{error.github}"></a>
|
||||||
<a href="https://discord.gg/Cn8pWhQRxZ" id="discord-button" target="_blank" th:text="#{joinDiscord}"></a>
|
<a href="https://discord.gg/HYmhKj45pU" id="discord-button" target="_blank" th:text="#{joinDiscord}"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
<p th:text="#{error.contactTip}"></p>
|
<p th:text="#{error.contactTip}"></p>
|
||||||
<div id="button-group">
|
<div id="button-group">
|
||||||
<a href="https://github.com/Stirling-Tools/Stirling-PDF/issues" id="github-button" target="_blank" th:text="#{error.githubSubmit}"></a>
|
<a href="https://github.com/Stirling-Tools/Stirling-PDF/issues" id="github-button" target="_blank" th:text="#{error.githubSubmit}"></a>
|
||||||
<a href="https://discord.gg/Cn8pWhQRxZ" id="discord-button" target="_blank" th:text="#{error.discordSubmit}"></a>
|
<a href="https://discord.gg/HYmhKj45pU" id="discord-button" target="_blank" th:text="#{error.discordSubmit}"></a>
|
||||||
</div>
|
</div>
|
||||||
<a th:href="@{'/'}" class="home-button" th:text="#{goHomepage}"></a>
|
<a th:href="@{'/'}" class="home-button" th:text="#{goHomepage}"></a>
|
||||||
<a data-bs-dismiss="modal" class="home-button" th:text="#{close}"></a>
|
<a data-bs-dismiss="modal" class="home-button" th:text="#{close}"></a>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ca_CA"> <img th:src="@{'/images/flags/es-ct.svg'}" alt="icon" width="20" height="15"> Català</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ca_CA"> <img th:src="@{'/images/flags/es-ct.svg'}" alt="icon" width="20" height="15"> Català</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="zh_CN"> <img th:src="@{'/images/flags/cn.svg'}" alt="icon" width="20" height="15"> 简体中文</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="zh_CN"> <img th:src="@{'/images/flags/cn.svg'}" alt="icon" width="20" height="15"> 简体中文</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="zh_TW"> <img th:src="@{'/images/flags/tw.svg'}" alt="icon" width="20" height="15"> 繁體中文</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="zh_TW"> <img th:src="@{'/images/flags/tw.svg'}" alt="icon" width="20" height="15"> 繁體中文</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="da_DK"> <img th:src="@{'/images/flags/dk.svg'}" alt="icon" width="20" height="15"> Dansk</a>
|
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="de_DE"> <img th:src="@{'/images/flags/de.svg'}" alt="icon" width="20" height="15"> Deutsch</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="de_DE"> <img th:src="@{'/images/flags/de.svg'}" alt="icon" width="20" height="15"> Deutsch</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="en_GB"> <img th:src="@{'/images/flags/gb.svg'}" alt="icon" width="20" height="15"> English (GB)</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="en_GB"> <img th:src="@{'/images/flags/gb.svg'}" alt="icon" width="20" height="15"> English (GB)</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="en_US"> <img th:src="@{'/images/flags/us.svg'}" alt="icon" width="20" height="15"> English (US)</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="en_US"> <img th:src="@{'/images/flags/us.svg'}" alt="icon" width="20" height="15"> English (US)</a>
|
||||||
@@ -12,7 +11,6 @@
|
|||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="es_ES"> <img th:src="@{'/images/flags/es.svg'}" alt="icon" width="20" height="15"> Español</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="es_ES"> <img th:src="@{'/images/flags/es.svg'}" alt="icon" width="20" height="15"> Español</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="fr_FR"> <img th:src="@{'/images/flags/fr.svg'}" alt="icon" width="20" height="15"> Français</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="fr_FR"> <img th:src="@{'/images/flags/fr.svg'}" alt="icon" width="20" height="15"> Français</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="id_ID"> <img th:src="@{'/images/flags/id.svg'}" alt="icon" width="20" height="15"> Indonesia</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="id_ID"> <img th:src="@{'/images/flags/id.svg'}" alt="icon" width="20" height="15"> Indonesia</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="id_ID"> <img th:src="@{'/images/flags/ie.svg'}" alt="icon" width="20" height="15"> Irish</a>
|
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="it_IT"> <img th:src="@{'/images/flags/it.svg'}" alt="icon" width="20" height="15"> Italiano</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="it_IT"> <img th:src="@{'/images/flags/it.svg'}" alt="icon" width="20" height="15"> Italiano</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="nl_NL"> <img th:src="@{'/images/flags/nl.svg'}" alt="icon" width="20" height="15"> Nederlands</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="nl_NL"> <img th:src="@{'/images/flags/nl.svg'}" alt="icon" width="20" height="15"> Nederlands</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL"> <img th:src="@{'/images/flags/pl.svg'}" alt="icon" width="20" height="15"> Polski</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL"> <img th:src="@{'/images/flags/pl.svg'}" alt="icon" width="20" height="15"> Polski</a>
|
||||||
@@ -33,6 +31,4 @@
|
|||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="cs_CZ"> <img th:src="@{'/images/flags/cz.svg'}" alt="icon" width="20" height="15"> Česky</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="cs_CZ"> <img th:src="@{'/images/flags/cz.svg'}" alt="icon" width="20" height="15"> Česky</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="hr_HR"> <img th:src="@{'/images/flags/hr.svg'}" alt="icon" width="20" height="15"> Hrvatski</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="hr_HR"> <img th:src="@{'/images/flags/hr.svg'}" alt="icon" width="20" height="15"> Hrvatski</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="no_NB"> <img th:src="@{'/images/flags/no.svg'}" alt="icon" width="20" height="15"> Norsk</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="no_NB"> <img th:src="@{'/images/flags/no.svg'}" alt="icon" width="20" height="15"> Norsk</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="th_TH"> <img th:src="@{'/images/flags/th.svg'}" alt="icon" width="20" height="15"> ไทย</a>
|
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="vi_VN"> <img th:src="@{'/images/flags/vn.svg'}" alt="icon" width="20" height="15"> Tiếng Việt</a>
|
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|||||||
@@ -391,7 +391,7 @@
|
|||||||
<a href="https://hub.docker.com/r/frooodle/s-pdf" class="mx-1" role="button" th:title="#{seeDockerHub}">
|
<a href="https://hub.docker.com/r/frooodle/s-pdf" class="mx-1" role="button" th:title="#{seeDockerHub}">
|
||||||
<img th:src="@{'/images/docker.svg'}" alt="docker">
|
<img th:src="@{'/images/docker.svg'}" alt="docker">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/Cn8pWhQRxZ" class="mx-1" role="button" th:title="#{joinDiscord}">
|
<a href="https://discord.gg/HYmhKj45pU" class="mx-1" role="button" th:title="#{joinDiscord}">
|
||||||
<img th:src="@{'/images/discord.svg'}" alt="discord">
|
<img th:src="@{'/images/discord.svg'}" alt="discord">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/sponsors/Frooodle" class="mx-1" role="button" th:title="#{donate}">
|
<a href="https://github.com/sponsors/Frooodle" class="mx-1" role="button" th:title="#{donate}">
|
||||||
|
|||||||
@@ -264,9 +264,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/*
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
const surveyVersion = "1.1";
|
<!-- const surveyVersion = "1.1";
|
||||||
const modal = new bootstrap.Modal(document.getElementById('surveyModal'));
|
const modal = new bootstrap.Modal(document.getElementById('surveyModal'));
|
||||||
const dontShowAgain = document.getElementById('dontShowAgain');
|
const dontShowAgain = document.getElementById('dontShowAgain');
|
||||||
const takeSurveyButton = document.getElementById('takeSurvey');
|
const takeSurveyButton = document.getElementById('takeSurvey');
|
||||||
@@ -294,8 +293,8 @@
|
|||||||
|
|
||||||
if (localStorage.getItem('dontShowSurvey')) {
|
if (localStorage.getItem('dontShowSurvey')) {
|
||||||
modal.hide();
|
modal.hide();
|
||||||
}
|
} -->
|
||||||
});*/
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -83,21 +83,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.decrementPage() : DraggableUtils.incrementPage()">
|
<button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.decrementPage() : DraggableUtils.incrementPage()">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-right" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-right" viewBox="0 0 16 16">
|
||||||
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6-6a.5.5 0 0 1 0-.708z"/>
|
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/>
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-outline-secondary" onclick="DraggableUtils.rotateElement(DraggableUtils.getLastInteracted(), -90)">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
|
||||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.418A6 6 0 1 1 8 2v1z"/>
|
|
||||||
<path d="M8 1a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0v-4A.5.5 0 0 1 8 1z"/>
|
|
||||||
<path d="M8 4.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5z"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-outline-secondary" onclick="DraggableUtils.rotateElement(DraggableUtils.getLastInteracted(), 90)">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
|
||||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.418A6 6 0 1 0 8 2v1z"/>
|
|
||||||
<path d="M8 1a.5.5 0 0 0-.5.5v4a.5.5 0 0 0 1 0v-4A.5.5 0 0 0 8 1z"/>
|
|
||||||
<path d="M8 4.5a.5.5 0 0 0-.5-.5h-4a.5.5 0 0 0 0 1h4a.5.5 0 0 0 .5-.5z"/>
|
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -117,7 +103,6 @@
|
|||||||
link.download = originalFileName + '_addedImage.pdf';
|
link.download = originalFileName + '_addedImage.pdf';
|
||||||
link.click();
|
link.click();
|
||||||
});
|
});
|
||||||
DraggableUtils.init();
|
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,9 +17,7 @@
|
|||||||
<span class="tool-header-text" th:text="#{autoRedact.header}"></span>
|
<span class="tool-header-text" th:text="#{autoRedact.header}"></span>
|
||||||
</div>
|
</div>
|
||||||
<form action="api/v1/security/auto-redact" method="post" enctype="multipart/form-data">
|
<form action="api/v1/security/auto-redact" method="post" enctype="multipart/form-data">
|
||||||
<div class="mb-3">
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
|
||||||
<input type="file" class="form-control" id="fileInput" name="fileInput" required accept="application/pdf">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="listOfText" class="form-label" th:text="#{autoRedact.textsToRedactLabel}"></label>
|
<label for="listOfText" class="form-label" th:text="#{autoRedact.textsToRedactLabel}"></label>
|
||||||
|
|||||||
@@ -247,20 +247,6 @@
|
|||||||
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/>
|
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-outline-secondary" onclick="DraggableUtils.rotateLeft()">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
|
||||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.418A6 6 0 1 1 8 2v1z"/>
|
|
||||||
<path d="M8 1a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0v-4A.5.5 0 0 1 8 1z"/>
|
|
||||||
<path d="M8 4.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5z"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-outline-secondary" onclick="DraggableUtils.rotateRight()">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
|
||||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.418A6 6 0 1 0 8 2v1z"/>
|
|
||||||
<path d="M8 1a.5.5 0 0 0-.5.5v4a.5.5 0 0 0 1 0v-4A.5.5 0 0 0 8 1z"/>
|
|
||||||
<path d="M8 4.5a.5.5 0 0 0-.5-.5h-4a.5.5 0 0 0 0 1h4a.5.5 0 0 0 .5-.5z"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -279,7 +265,6 @@
|
|||||||
link.download = originalFileName + '_signed.pdf';
|
link.download = originalFileName + '_signed.pdf';
|
||||||
link.click();
|
link.click();
|
||||||
});
|
});
|
||||||
DraggableUtils.init();
|
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class FileToPdfTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testConvertHtmlToPdf() {
|
public void testConvertHtmlToPdf() {
|
||||||
HTMLToPdfRequest request = new HTMLToPdfRequest();
|
HTMLToPdfRequest request = new HTMLToPdfRequest();
|
||||||
byte[] fileBytes = new byte[0]; // Sample file bytes
|
byte[] fileBytes = new byte[10]; // Sample file bytes
|
||||||
String fileName = "test.html"; // Sample file name
|
String fileName = "test.html"; // Sample file name
|
||||||
boolean htmlFormatsInstalled = true; // Sample boolean value
|
boolean htmlFormatsInstalled = true; // Sample boolean value
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package stirling.software.SPDF;
|
package stirling.software.SPDF.utils;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -15,6 +14,7 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.SPdfApplication;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@@ -43,43 +43,12 @@ public class SPdfApplicationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMainApplicationStartup() throws IOException, InterruptedException {
|
public void testMainApplicationStartup() throws IOException, InterruptedException {
|
||||||
// Setup mock environment for the main method
|
|
||||||
Path configPath = Path.of("test/configs");
|
|
||||||
Path settingsPath = Paths.get("test/configs/settings.yml");
|
|
||||||
Path customSettingsPath = Paths.get("test/configs/custom_settings.yml");
|
|
||||||
Path staticPath = Path.of("test/customFiles/static/");
|
|
||||||
Path templatesPath = Path.of("test/customFiles/templates/");
|
|
||||||
|
|
||||||
// Ensure the files do not exist for the test
|
|
||||||
if (Files.exists(settingsPath)) {
|
|
||||||
Files.delete(settingsPath);
|
|
||||||
}
|
|
||||||
if (Files.exists(customSettingsPath)) {
|
|
||||||
Files.delete(customSettingsPath);
|
|
||||||
}
|
|
||||||
if (Files.exists(staticPath)) {
|
|
||||||
Files.delete(staticPath);
|
|
||||||
}
|
|
||||||
if (Files.exists(templatesPath)) {
|
|
||||||
Files.delete(templatesPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the directories are created for testing
|
|
||||||
Files.createDirectories(configPath);
|
|
||||||
Files.createDirectories(staticPath);
|
|
||||||
Files.createDirectories(templatesPath);
|
|
||||||
|
|
||||||
Files.createFile(settingsPath);
|
|
||||||
Files.createFile(customSettingsPath);
|
|
||||||
|
|
||||||
// Run the main method
|
// Run the main method
|
||||||
SPdfApplication.main(new String[]{});
|
SPdfApplication.main(new String[]{});
|
||||||
|
|
||||||
// Verify that the directories were created
|
// Verify that the directories were created
|
||||||
assertTrue(Files.exists(settingsPath));
|
assertTrue(Files.exists(Path.of("customFiles/static/")));
|
||||||
assertTrue(Files.exists(customSettingsPath));
|
assertTrue(Files.exists(Path.of("customFiles/templates/")));
|
||||||
assertTrue(Files.exists(staticPath));
|
|
||||||
assertTrue(Files.exists(templatesPath));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
3
test.sh
3
test.sh
@@ -88,9 +88,6 @@ main() {
|
|||||||
passed_tests+=("Stirling-PDF-Regression")
|
passed_tests+=("Stirling-PDF-Regression")
|
||||||
else
|
else
|
||||||
failed_tests+=("Stirling-PDF-Regression")
|
failed_tests+=("Stirling-PDF-Regression")
|
||||||
echo "Printing docker logs of failed regression"
|
|
||||||
docker logs "Stirling-PDF"
|
|
||||||
echo "Printed docker logs of failed regression"
|
|
||||||
fi
|
fi
|
||||||
cd ..
|
cd ..
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user