Compare commits

...

14 Commits

Author SHA1 Message Date
Anthony Stirling
f474651f36 lang, save to browser (#923) 2024-03-17 09:33:05 +00:00
tongkl1
11193b1b6d Fix typo in example yaml file (#922) 2024-03-16 09:49:28 +00:00
github-actions[bot]
3066b3e500 Update 3rd Party Licenses (#919)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-03-14 23:00:38 +00:00
dependabot[bot]
217f112bc4 Bump com.google.zxing:core from 3.5.2 to 3.5.3 (#779)
Bumps [com.google.zxing:core](https://github.com/zxing/zxing) from 3.5.2 to 3.5.3.
- [Release notes](https://github.com/zxing/zxing/releases)
- [Changelog](https://github.com/zxing/zxing/blob/master/CHANGES)
- [Commits](https://github.com/zxing/zxing/compare/zxing-3.5.2...zxing-3.5.3)

---
updated-dependencies:
- dependency-name: com.google.zxing:core
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-03-14 22:59:27 +00:00
github-actions[bot]
e1bb0cf5ec Update 3rd Party Licenses (#914)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-03-13 22:45:32 +00:00
Anthony Stirling
3930c25a75 Frooodle patch 2 (#913)
* Update licenses-update.yml

* Update build.gradle
2024-03-13 22:34:24 +00:00
Anthony Stirling
b27e79cb52 Update build.gradle (#912) 2024-03-13 22:29:55 +00:00
Anthony Stirling
daf6486b86 Update licenses-update.yml (#911) 2024-03-13 22:26:39 +00:00
Ludy
1af41f8ea5 🔨 add Developer tools/scripts (#828)
* 🔨 add Developer tools

* Update downloader.js

* Update game.js

* Update .pre-commit-config.yaml

* Update sync_versions.yml

* removed: mixed line ending tool

* Update swagger.yml

* Update push-docker.yml

* Update build.yml

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-03-13 22:18:15 +00:00
Listiges Känguru
70e4ac21df Update messages_de_DE.properties (#903)
Added missing translations, improved some existing translations.
2024-03-13 22:11:43 +00:00
Anthony Stirling
95d9d85ca2 dep bumps and nonroot bypass (#910)
* dep bumps and nonroot bypass

* log changing
2024-03-13 22:09:56 +00:00
Ludy
9cc7a49d12 Enforcing Username Uniqueness (#906)
* Enforcing Username Uniqueness

Changes in UserService.java:

Added a new method findByUsername to allow searching for usernames regardless of case sensitivity.
Added a new method isUsernameValid to validate the username.
Changes in UserController.java:

Updated the changeUsername method to ensure the new username is valid before changing it.
Updated the editUser method to ensure the new username is unique and valid.
Changes in UserRepository.java:

Added a custom JPQL query to search for usernames regardless of case sensitivity.
Changes in HTML templates (account.html and addUsers.html):

Error messages are displayed if a username is invalid or already exists.

* JPAs auto
2024-03-13 22:09:16 +00:00
Anthony Stirling
ae73595335 Number of fixes and making pipline LIVE ! (#907)
Closes #889 and #332
#710
#901
#885
2024-03-13 19:15:10 +00:00
pavedroad
ac620082ec chore: fix some typos (#900)
Signed-off-by: pavedroad <qcqs@outlook.com>
2024-03-12 19:42:15 -04:00
72 changed files with 1024 additions and 460 deletions

51
.github/scripts/check_duplicates.py vendored Normal file
View File

@@ -0,0 +1,51 @@
import sys
def find_duplicate_keys(file_path):
"""
Finds duplicate keys in a properties file and returns their occurrences.
This function reads a properties file, identifies any keys that occur more than
once, and returns a dictionary with these keys and the line numbers of their occurrences.
Parameters:
file_path (str): The path to the properties file to be checked.
Returns:
dict: A dictionary where each key is a duplicated key in the file, and the value is a list
of line numbers where the key occurs.
"""
with open(file_path, "r", encoding="utf-8") as file:
lines = file.readlines()
keys = {}
duplicates = {}
for line_number, line in enumerate(lines, start=1):
line = line.strip()
if line and not line.startswith("#") and "=" in line:
key = line.split("=", 1)[0].strip()
if key in keys:
# If the key already exists, add the current line number
duplicates.setdefault(key, []).append(line_number)
# Also add the first instance of the key if not already done
if keys[key] not in duplicates[key]:
duplicates[key].insert(0, keys[key])
else:
# Store the line number of the first instance of the key
keys[key] = line_number
return duplicates
if __name__ == "__main__":
failed = False
for ar in sys.argv[1:]:
duplicates = find_duplicate_keys(ar)
if duplicates:
for key, lines in duplicates.items():
lines_str = ", ".join(map(str, lines))
print(f"{key} duplicated in {ar} on lines {lines_str}")
failed = True
if failed:
sys.exit(1)

84
.github/scripts/check_tabulator.py vendored Normal file
View File

@@ -0,0 +1,84 @@
"""check_tabulator.py"""
import argparse
import sys
def check_tabs(file_path):
"""
Checks for tabs in the specified file.
Args:
file_path (str): The path to the file to be checked.
Returns:
bool: True if tabs are found, False otherwise.
"""
with open(file_path, "r", encoding="utf-8") as file:
content = file.read()
if "\t" in content:
print(f"Tab found in {file_path}")
return True
return False
def replace_tabs_with_spaces(file_path, replace_with=" "):
"""
Replaces tabs with a specified number of spaces in the file.
Args:
file_path (str): The path to the file where tabs will be replaced.
replace_with (str): The character(s) to replace tabs with. Defaults to two spaces.
"""
with open(file_path, "r", encoding="utf-8") as file:
content = file.read()
updated_content = content.replace("\t", replace_with)
with open(file_path, "w", encoding="utf-8") as file:
file.write(updated_content)
def main():
"""
Main function to replace tabs with spaces in the provided files.
The replacement character and files to check are taken from command line arguments.
"""
# Create ArgumentParser instance
parser = argparse.ArgumentParser(
description="Replace tabs in files with specified characters."
)
# Define optional argument `--replace_with`
parser.add_argument(
"--replace_with",
default=" ",
help="Character(s) to replace tabs with. Default is two spaces.",
)
# Define argument for file paths
parser.add_argument("files", metavar="FILE", nargs="+", help="Files to process.")
# Parse arguments
args = parser.parse_args()
# Extract replacement characters and files from the parsed arguments
replace_with = args.replace_with
files_checked = args.files
error = False
for file_path in files_checked:
if check_tabs(file_path):
replace_tabs_with_spaces(file_path, replace_with)
error = True
if error:
print("Error: Originally found tabs in HTML files, now replaced.")
sys.exit(1)
sys.exit(0)
if __name__ == "__main__":
main()

67
.github/scripts/gradle_to_chart.py vendored Normal file
View File

@@ -0,0 +1,67 @@
import re
import yaml
# Paths to the files
chart_yaml_path = "chart/stirling-pdf/Chart.yaml"
gradle_path = "build.gradle"
def get_chart_version(path):
"""
Reads the appVersion from Chart.yaml.
Args:
path (str): The file path to the Chart.yaml.
Returns:
str: The appVersion if found, otherwise an empty string.
"""
with open(path, encoding="utf-8") as file:
chart_yaml = yaml.safe_load(file)
return chart_yaml.get("appVersion", "")
def get_gradle_version(path):
"""
Extracts the version from build.gradle.
Args:
path (str): The file path to the build.gradle.
Returns:
str: The version if found, otherwise an empty string.
"""
with open(path, encoding="utf-8") as file:
for line in file:
if "version =" in line:
# Extracts the value after 'version ='
return re.search(r'version\s*=\s*[\'"](.+?)[\'"]', line).group(1)
return ""
def update_chart_version(path, new_version):
"""
Updates the appVersion in Chart.yaml with a new version.
Args:
path (str): The file path to the Chart.yaml.
new_version (str): The new version to update to.
"""
with open(path, encoding="utf-8") as file:
chart_yaml = yaml.safe_load(file)
chart_yaml["appVersion"] = new_version
with open(path, "w", encoding="utf-8") as file:
yaml.safe_dump(chart_yaml, file)
# Main logic
chart_version = get_chart_version(chart_yaml_path)
gradle_version = get_gradle_version(gradle_path)
if chart_version != gradle_version:
print(
f"Versions do not match. Updating Chart.yaml from {chart_version} to {gradle_version}."
)
update_chart_version(chart_yaml_path, gradle_version)
else:
print("Versions match. No update required.")

View File

@@ -3,8 +3,14 @@ name: "Build repo"
on: on:
push: push:
branches: [ "main" ] branches: [ "main" ]
paths-ignore:
- ".github/**"
- "**/*.md"
pull_request: pull_request:
branches: [ "main" ] branches: [ "main" ]
paths-ignore:
- ".github/**"
- "**/*.md"
jobs: jobs:
build: build:

View File

@@ -32,17 +32,30 @@ jobs:
run: | run: |
mv build/reports/dependency-license/index.json src/main/resources/static/3rdPartyLicenses.json mv build/reports/dependency-license/index.json src/main/resources/static/3rdPartyLicenses.json
- name: Check for Changes - name: Set up git config
id: git-check run: |
git config --global user.email "GitHub Action <action@github.com>"
git config --global user.name "GitHub Action <action@github.com>"
- name: Run git add
run: | run: |
git add src/main/resources/static/3rdPartyLicenses.json git add src/main/resources/static/3rdPartyLicenses.json
git diff --staged --exit-code || echo "changes=true" >> $GITHUB_ENV git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
- name: Commit and Push Changes - name: Create Pull Request
if: env.changes == 'true' if: env.CHANGES_DETECTED == 'true'
run: | uses: peter-evans/create-pull-request@v3
git config --global user.name 'Stirling-PDF-Bot' with:
git config --global user.email 'Stirling-PDF-Bot@stirlingtools.com' token: ${{ secrets.GITHUB_TOKEN }}
git commit -m "Update 3rd Party Licenses" commit-message: "Update 3rd Party Licenses"
git push committer: GitHub Action <action@github.com>
author: GitHub Action <action@github.com>
signoff: true
branch: update-3rd-party-licenses
title: "Update 3rd Party Licenses"
body: |
Auto-generated by [create-pull-request][1]
[1]: https://github.com/peter-evans/create-pull-request
draft: false
delete-branch: true

View File

@@ -6,6 +6,10 @@ on:
branches: branches:
- master - master
- main - main
paths-ignore:
- ".github/**"
- "**/*.md"
permissions: permissions:
contents: read contents: read
packages: write packages: write

View File

@@ -5,6 +5,9 @@ on:
push: push:
branches: branches:
- master - master
paths-ignore:
- ".github/**"
- "**/*.md"
jobs: jobs:
push: push:

51
.github/workflows/sync_versions.yml vendored Normal file
View File

@@ -0,0 +1,51 @@
name: Sync Versions
on:
push:
branches:
- main
paths:
- "build.gradle"
permissions:
contents: write
pull-requests: write
jobs:
sync-versions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
- name: Set up Python
uses: actions/setup-python@v5.0.0
with:
python-version: '3.x'
- name: Install dependencies
run: pip install pyyaml
- name: Sync versions
run: python .github/scripts/gradle_to_chart.py
- name: Set up git config
run: |
git config --global user.email "GitHub Action <action@github.com>"
git config --global user.name "GitHub Action <action@github.com>"
- name: Run git add
run: |
git add .
git diff --staged --quiet || git commit -m ":floppy_disk: Sync Versions
> Made via sync_versions.yml" || echo "no changes"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Update files
committer: GitHub Action <action@github.com>
author: GitHub Action <action@github.com>
signoff: true
branch: sync_version
title: ":floppy_disk: Update Version"
body: |
Auto-generated by [create-pull-request][1]
[1]: https://github.com/peter-evans/create-pull-request
draft: false
delete-branch: true

37
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,37 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.1
hooks:
- id: ruff
args:
- --fix
- --line-length=127
files: ^((.github/scripts)/.+)?[^/]+\.py$
- id: ruff-format
files: ^((.github/scripts)/.+)?[^/]+\.py$
- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
hooks:
- id: codespell
args:
- --ignore-words-list=
- --skip="./.*,*.csv,*.json,*.ambr"
- --quiet-level=2
files: \.(properties|html|css|js|py|md)$
exclude: (.vscode|.devcontainer|src/main/resources|Dockerfile)
- repo: local
hooks:
- id: check-duplicate-properties-keys
name: Check Duplicate Properties Keys
entry: python .github/scripts/check_duplicates.py
language: python
files: ^(src)/.+\.properties$
- repo: local
hooks:
- id: check-html-tabs
name: Check HTML for tabs
# args: ["--replace_with= "]
entry: python .github/scripts/check_tabulator.py
language: python
exclude: ^src/main/resources/static/pdfjs/
files: ^.*(\.html|\.css|\.js)$

View File

@@ -1,13 +1,5 @@
## User Guide for Local Directory Scanning and File Processing ## User Guide for Local Directory Scanning and File Processing
### Whilst Pipelines are in alpha...
You must enable this alpha functionality by setting
```yaml
system:
enableAlphaFunctionality: true
```
To true like in the above for your `/config/settings.yml` file, after restarting Stirling-PDF you should see both UI and folder scanning enabled.
### Setting Up Watched Folders: ### Setting Up Watched Folders:
- Create a folder where you want your files to be monitored. This is your 'watched folder'. - Create a folder where you want your files to be monitored. This is your 'watched folder'.
- The default directory for this is `./pipeline/watchedFolders/` - The default directory for this is `./pipeline/watchedFolders/`

View File

@@ -3,7 +3,7 @@
This document provides instructions on how to add additional language packs for the OCR tab in Stirling-PDF, both inside and outside of Docker. This document provides instructions on how to add additional language packs for the OCR tab in Stirling-PDF, both inside and outside of Docker.
## My OCR used to work and now doesn't! ## My OCR used to work and now doesn't!
The paths have changed for the tessadata locations on new docker images, please use ``/usr/share/tessdata`` (Others should still work for backwards compatability but might not) The paths have changed for the tessadata locations on new docker images, please use ``/usr/share/tessdata`` (Others should still work for backwards compatibility but might not)
## How does the OCR Work ## How does the OCR Work
Stirling-PDF uses [OCRmyPDF](https://github.com/ocrmypdf/OCRmyPDF) which in turn uses tesseract for its text recognition. Stirling-PDF uses [OCRmyPDF](https://github.com/ocrmypdf/OCRmyPDF) which in turn uses tesseract for its text recognition.

View File

@@ -1,13 +1,6 @@
# Pipeline Configuration and Usage Tutorial # Pipeline Configuration and Usage Tutorial
- Configure the pipeline config file and input files to run files against it
## Whilst Pipelines are in alpha... - For reuse, download the config file and re-upload it when needed, or place it in /pipeline/defaultWebUIConfigs/ to auto-load in the web UI for all users
You must enable this alpha functionality by setting
```yaml
system:
enableAlphaFunctionality: true
```
To true like in the above for your `/config/settings.yml` file, after restarting Stirling-PDF you should see both UI and folder scanning enabled.
## Steps to Configure and Use Your Pipeline ## Steps to Configure and Use Your Pipeline
@@ -40,3 +33,12 @@ To true like in the above for your `/config/settings.yml` file, after restarting
10. **Note on Web UI Limitations** 10. **Note on Web UI Limitations**
- The current web UI version does not support operations that require multiple different types of inputs, such as adding a separate image to a PDF. - The current web UI version does not support operations that require multiple different types of inputs, such as adding a separate image to a PDF.
### Current Limitations
- Cannot have more than one of the same operation
- Cannot input additional files via UI
- All files and operations run in serial mode

View File

@@ -1,6 +1,6 @@
plugins { plugins {
id 'java' id 'java'
id 'org.springframework.boot' version '3.2.2' id 'org.springframework.boot' version '3.2.3'
id 'io.spring.dependency-management' version '1.1.3' id 'io.spring.dependency-management' version '1.1.3'
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"
@@ -12,8 +12,7 @@ plugins {
import com.github.jk1.license.render.* import com.github.jk1.license.render.*
group = 'stirling.software' group = 'stirling.software'
version = '0.22.3'
version = '0.22.2'
sourceCompatibility = '17' sourceCompatibility = '17'
repositories { repositories {
@@ -21,7 +20,6 @@ repositories {
} }
licenseReport { licenseReport {
renderers = [new JsonReportRenderer()] renderers = [new JsonReportRenderer()]
} }
@@ -49,7 +47,6 @@ openApi {
outputFileName = "SwaggerDoc.json" outputFileName = "SwaggerDoc.json"
} }
launch4j { launch4j {
icon = "${projectDir}/src/main/resources/static/favicon.ico" icon = "${projectDir}/src/main/resources/static/favicon.ico"
@@ -88,26 +85,26 @@ spotless {
dependencies { dependencies {
//security updates //security updates
implementation 'ch.qos.logback:logback-classic:1.4.14' implementation 'ch.qos.logback:logback-classic:1.5.3'
implementation 'ch.qos.logback:logback-core:1.4.14' implementation 'ch.qos.logback:logback-core:1.5.3'
implementation 'org.springframework:spring-webmvc:6.1.3' implementation 'org.springframework:spring-webmvc:6.1.4'
implementation("io.github.pixee:java-security-toolkit:1.1.2") implementation("io.github.pixee:java-security-toolkit:1.1.2")
implementation 'org.yaml:snakeyaml:2.2' implementation 'org.yaml:snakeyaml:2.2'
implementation 'org.springframework.boot:spring-boot-starter-web:3.2.2' implementation 'org.springframework.boot:spring-boot-starter-web:3.2.3'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.2.2' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.2.3'
if (System.getenv('DOCKER_ENABLE_SECURITY') != 'false') { if (System.getenv('DOCKER_ENABLE_SECURITY') != 'false') {
implementation 'org.springframework.boot:spring-boot-starter-security:3.2.2' implementation 'org.springframework.boot:spring-boot-starter-security:3.2.3'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE'
implementation "org.springframework.boot:spring-boot-starter-data-jpa:3.2.2" implementation "org.springframework.boot:spring-boot-starter-data-jpa:3.2.3"
//2.2.x requires rebuild of DB file.. need migration path //2.2.x requires rebuild of DB file.. need migration path
implementation "com.h2database:h2:2.1.214" implementation "com.h2database:h2:2.1.214"
} }
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.2.2' testImplementation 'org.springframework.boot:spring-boot-starter-test:3.2.3'
// Batik // Batik
implementation 'org.apache.xmlgraphics:batik-all:1.17' implementation 'org.apache.xmlgraphics:batik-all:1.17'
@@ -150,9 +147,9 @@ dependencies {
implementation 'org.bouncycastle:bcprov-jdk18on:1.77' implementation 'org.bouncycastle:bcprov-jdk18on:1.77'
implementation 'org.bouncycastle:bcpkix-jdk18on:1.77' implementation 'org.bouncycastle:bcpkix-jdk18on:1.77'
implementation 'org.springframework.boot:spring-boot-starter-actuator:3.2.2' implementation 'org.springframework.boot:spring-boot-starter-actuator:3.2.3'
implementation 'io.micrometer:micrometer-core:1.12.3' implementation 'io.micrometer:micrometer-core:1.12.3'
implementation group: 'com.google.zxing', name: 'core', version: '3.5.2' implementation group: 'com.google.zxing', name: 'core', version: '3.5.3'
// https://mvnrepository.com/artifact/org.commonmark/commonmark // https://mvnrepository.com/artifact/org.commonmark/commonmark
implementation 'org.commonmark:commonmark:0.21.0' implementation 'org.commonmark:commonmark:0.21.0'
implementation 'org.commonmark:commonmark-ext-gfm-tables:0.21.0' implementation 'org.commonmark:commonmark-ext-gfm-tables:0.21.0'
@@ -161,7 +158,7 @@ dependencies {
implementation 'com.fathzer:javaluator:3.0.3' implementation 'com.fathzer:javaluator:3.0.3'
developmentOnly("org.springframework.boot:spring-boot-devtools:3.2.2") developmentOnly("org.springframework.boot:spring-boot-devtools:3.2.3")
compileOnly 'org.projectlombok:lombok:1.18.30' compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.28' annotationProcessor 'org.projectlombok:lombok:1.18.28'
} }

View File

@@ -1,5 +1,5 @@
apiVersion: v2 apiVersion: v2
appVersion: 0.20.2 appVersion: 0.22.3
description: locally hosted web application that allows you to perform various operations on PDF files description: locally hosted web application that allows you to perform various operations on PDF files
home: https://github.com/Stirling-Tools/Stirling-PDF home: https://github.com/Stirling-Tools/Stirling-PDF
keywords: keywords:

View File

@@ -22,7 +22,7 @@ services:
DOCKER_ENABLE_SECURITY: "true" DOCKER_ENABLE_SECURITY: "true"
SECURITY_ENABLELOGIN: "true" SECURITY_ENABLELOGIN: "true"
PUID: 1002 PUID: 1002
GGID: 1002 PGID: 1002
UMASK: "022" UMASK: "022"
SYSTEM_DEFAULTLOCALE: en-US SYSTEM_DEFAULTLOCALE: en-US
UI_APPNAME: Stirling-PDF UI_APPNAME: Stirling-PDF

View File

@@ -10,14 +10,20 @@ if [ ! -z "$PGID" ] && [ "$PGID" != "$(getent group stirlingpdfgroup | cut -d: -
fi fi
umask "$UMASK" || true umask "$UMASK" || true
echo "Setting permissions and ownership for necessary directories..."
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /logs /scripts /usr/share/fonts/opentype/noto /usr/share/tessdata /configs /customFiles /pipeline /app.jar || true
chmod -R 755 /logs /scripts /usr/share/fonts/opentype/noto /usr/share/tessdata /configs /customFiles /pipeline /app.jar || true
if [[ "$INSTALL_BOOK_AND_ADVANCED_HTML_OPS" == "true" ]]; then if [[ "$INSTALL_BOOK_AND_ADVANCED_HTML_OPS" == "true" ]]; then
apk add --no-cache calibre@testing apk add --no-cache calibre@testing
fi fi
/scripts/download-security-jar.sh /scripts/download-security-jar.sh
# Run the main command echo "Setting permissions and ownership for necessary directories..."
exec su-exec stirlingpdfuser "$@" if chown -R stirlingpdfuser:stirlingpdfgroup $HOME /logs /scripts /usr/share/fonts/opentype/noto /usr/share/tessdata /configs /customFiles /pipeline /app.jar; then
chmod -R 755 /logs /scripts /usr/share/fonts/opentype/noto /usr/share/tessdata /configs /customFiles /pipeline /app.jar || true
# If chown succeeds, execute the command as stirlingpdfuser
exec su-exec stirlingpdfuser "$@"
else
# If chown fails, execute the command without changing the user context
echo "[WARN] Chown failed, running as host user"
exec "$@"
fi

View File

@@ -24,12 +24,6 @@ if [ ! -z "$PGID" ] && [ "$PGID" != "$(getent group stirlingpdfgroup | cut -d: -
fi fi
umask "$UMASK" || true umask "$UMASK" || true
echo "Setting permissions and ownership for necessary directories..."
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /logs /scripts /usr/share/fonts/opentype/noto /usr/share/tessdata /configs /customFiles /pipeline /app.jar || true
chmod -R 755 /logs /scripts /usr/share/fonts/opentype/noto /usr/share/tessdata /configs /customFiles /pipeline /app.jar || true
# Check if TESSERACT_LANGS environment variable is set and is not empty # Check if TESSERACT_LANGS environment variable is set and is not empty
if [[ -n "$TESSERACT_LANGS" ]]; then if [[ -n "$TESSERACT_LANGS" ]]; then
@@ -50,9 +44,16 @@ if [[ "$INSTALL_BOOK_AND_ADVANCED_HTML_OPS" == "true" ]]; then
apk add --no-cache calibre@testing apk add --no-cache calibre@testing
fi fi
/scripts/download-security-jar.sh /scripts/download-security-jar.sh
# Run the main command and switch to stirling user for rest of run echo "Setting permissions and ownership for necessary directories..."
exec su-exec stirlingpdfuser "$@" # Attempt to change ownership of directories and files
if chown -R stirlingpdfuser:stirlingpdfgroup $HOME /logs /scripts /usr/share/fonts/opentype/noto /usr/share/tessdata /configs /customFiles /pipeline /app.jar; then
chmod -R 755 /logs /scripts /usr/share/fonts/opentype/noto /usr/share/tessdata /configs /customFiles /pipeline /app.jar || true
# If chown succeeds, execute the command as stirlingpdfuser
exec su-exec stirlingpdfuser "$@"
else
# If chown fails, execute the command without changing the user context
echo "[WARN] Chown failed, running as host user"
exec "$@"
fi

View File

@@ -82,7 +82,7 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter() response.getWriter()
.write( .write(
"Authentication required. Please provide a X-API-KEY in request header.\nThis is found in Settings -> Account Settings -> API Key\nAlternativly you can disable authentication if this is unexpected"); "Authentication required. Please provide a X-API-KEY in request header.\nThis is found in Settings -> Account Settings -> API Key\nAlternatively you can disable authentication if this is unexpected");
return; return;
} }
} }

View File

@@ -176,6 +176,10 @@ public class UserService implements UserServiceInterface {
return userRepository.findByUsername(username); return userRepository.findByUsername(username);
} }
public Optional<User> findByUsernameIgnoreCase(String username) {
return userRepository.findByUsernameIgnoreCase(username);
}
public void changeUsername(User user, String newUsername) { public void changeUsername(User user, String newUsername) {
user.setUsername(newUsername); user.setUsername(newUsername);
userRepository.save(user); userRepository.save(user);
@@ -194,4 +198,8 @@ public class UserService implements UserServiceInterface {
public boolean isPasswordCorrect(User user, String currentPassword) { public boolean isPasswordCorrect(User user, String currentPassword) {
return passwordEncoder.matches(currentPassword, user.getPassword()); return passwordEncoder.matches(currentPassword, user.getPassword());
} }
public boolean isUsernameValid(String username) {
return username.matches("[a-zA-Z0-9]+");
}
} }

View File

@@ -61,11 +61,16 @@ public class UserController {
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response, HttpServletResponse response,
RedirectAttributes redirectAttributes) { RedirectAttributes redirectAttributes) {
if (!userService.isUsernameValid(newUsername)) {
return new RedirectView("/account?messageType=invalidUsername");
}
if (principal == null) { if (principal == null) {
return new RedirectView("/account?messageType=notAuthenticated"); return new RedirectView("/account?messageType=notAuthenticated");
} }
Optional<User> userOpt = userService.findByUsername(principal.getName()); Optional<User> userOpt = userService.findByUsernameIgnoreCase(principal.getName());
if (userOpt == null || userOpt.isEmpty()) { if (userOpt == null || userOpt.isEmpty()) {
return new RedirectView("/account?messageType=userNotFound"); return new RedirectView("/account?messageType=userNotFound");
@@ -73,6 +78,10 @@ public class UserController {
User user = userOpt.get(); User user = userOpt.get();
if (user.getUsername().equals(newUsername)) {
return new RedirectView("/account?messageType=usernameExists");
}
if (!userService.isPasswordCorrect(user, currentPassword)) { if (!userService.isPasswordCorrect(user, currentPassword)) {
return new RedirectView("/account?messageType=incorrectPassword"); return new RedirectView("/account?messageType=incorrectPassword");
} }
@@ -186,6 +195,18 @@ public class UserController {
@RequestParam(name = "forceChange", required = false, defaultValue = "false") @RequestParam(name = "forceChange", required = false, defaultValue = "false")
boolean forceChange) { boolean forceChange) {
if (!userService.isUsernameValid(username)) {
return new RedirectView("/addUsers?messageType=invalidUsername");
}
Optional<User> userOpt = userService.findByUsernameIgnoreCase(username);
if (userOpt.isPresent()) {
User user = userOpt.get();
if (user != null && user.getUsername().equalsIgnoreCase(username)) {
return new RedirectView("/addUsers?messageType=usernameExists");
}
}
if (userService.usernameExists(username)) { if (userService.usernameExists(username)) {
return new RedirectView("/addUsers?messageType=usernameExists"); return new RedirectView("/addUsers?messageType=usernameExists");
} }

View File

@@ -37,7 +37,7 @@ public class ConvertBookToPDFController {
if (!bookAndHtmlFormatsInstalled) { if (!bookAndHtmlFormatsInstalled) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"bookAndHtmlFormatsInstalled flag is False, this functionality is not avaiable"); "bookAndHtmlFormatsInstalled flag is False, this functionality is not available");
} }
if (fileInput == null) { if (fileInput == null) {

View File

@@ -45,7 +45,7 @@ public class ConvertPDFToBookController {
if (!bookAndHtmlFormatsInstalled) { if (!bookAndHtmlFormatsInstalled) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"bookAndHtmlFormatsInstalled flag is False, this functionality is not avaiable"); "bookAndHtmlFormatsInstalled flag is False, this functionality is not available");
} }
if (fileInput == null) { if (fileInput == null) {

View File

@@ -130,7 +130,7 @@ public class AutoRenameController {
// Sanitize the header string by removing characters not allowed in a filename. // Sanitize the header string by removing characters not allowed in a filename.
if (header != null && header.length() < 255) { if (header != null && header.length() < 255) {
header = header.replaceAll("[/\\\\?%*:|\"<>]", ""); header = header.replaceAll("[/\\\\?%*:|\"<>]", "").trim();
return WebResponseUtils.pdfDocToWebResponse(document, header + ".pdf"); return WebResponseUtils.pdfDocToWebResponse(document, header + ".pdf");
} else { } else {
logger.info("File has no good title to be found"); logger.info("File has no good title to be found");

View File

@@ -58,7 +58,7 @@ public class AutoSplitPdfController {
PDDocument document = Loader.loadPDF(file.getBytes()); PDDocument document = Loader.loadPDF(file.getBytes());
PDFRenderer pdfRenderer = new PDFRenderer(document); PDFRenderer pdfRenderer = new PDFRenderer(document);
pdfRenderer.setSubsamplingAllowed(true);
List<PDDocument> splitDocuments = new ArrayList<>(); List<PDDocument> splitDocuments = new ArrayList<>();
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>(); List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();

View File

@@ -59,7 +59,7 @@ public class BlankPageController {
List<Integer> pagesToKeepIndex = new ArrayList<>(); List<Integer> pagesToKeepIndex = new ArrayList<>();
int pageIndex = 0; int pageIndex = 0;
PDFRenderer pdfRenderer = new PDFRenderer(document); PDFRenderer pdfRenderer = new PDFRenderer(document);
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);

View File

@@ -2,9 +2,7 @@ package stirling.software.SPDF.controller.api.misc;
import java.awt.Image; import java.awt.Image;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
@@ -75,194 +73,208 @@ public class CompressController {
long inputFileSize = Files.size(tempInputFile); long inputFileSize = Files.size(tempInputFile);
// Prepare the output file path // Prepare the output file path
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
// Determine initial optimization level based on expected size reduction, only if in
// autoMode
if (autoMode) {
double sizeReductionRatio = expectedOutputSize / (double) inputFileSize;
if (sizeReductionRatio > 0.7) {
optimizeLevel = 1;
} else if (sizeReductionRatio > 0.5) {
optimizeLevel = 2;
} else if (sizeReductionRatio > 0.35) {
optimizeLevel = 3;
} else {
optimizeLevel = 3;
}
}
boolean sizeMet = false;
while (!sizeMet && optimizeLevel <= 4) {
// Prepare the Ghostscript command
List<String> command = new ArrayList<>();
command.add("gs");
command.add("-sDEVICE=pdfwrite");
command.add("-dCompatibilityLevel=1.4");
switch (optimizeLevel) {
case 1:
command.add("-dPDFSETTINGS=/prepress");
break;
case 2:
command.add("-dPDFSETTINGS=/printer");
break;
case 3:
command.add("-dPDFSETTINGS=/ebook");
break;
case 4:
command.add("-dPDFSETTINGS=/screen");
break;
default:
command.add("-dPDFSETTINGS=/default");
}
command.add("-dNOPAUSE");
command.add("-dQUIET");
command.add("-dBATCH");
command.add("-sOutputFile=" + tempOutputFile.toString());
command.add(tempInputFile.toString());
ProcessExecutorResult returnCode =
ProcessExecutor.getInstance(ProcessExecutor.Processes.GHOSTSCRIPT)
.runCommandWithOutputHandling(command);
// Check if file size is within expected size or not auto mode so instantly finish
long outputFileSize = Files.size(tempOutputFile);
if (outputFileSize <= expectedOutputSize || !autoMode) {
sizeMet = true;
} else {
// Increase optimization level for next iteration
optimizeLevel++;
if (autoMode && optimizeLevel > 3) {
System.out.println("Skipping level 4 due to bad results in auto mode");
sizeMet = true;
} else if (optimizeLevel == 5) {
Path tempOutputFile = null;
byte[] pdfBytes;
try {
tempOutputFile = Files.createTempFile("output_", ".pdf");
// Determine initial optimization level based on expected size reduction, only if in
// autoMode
if (autoMode) {
double sizeReductionRatio = expectedOutputSize / (double) inputFileSize;
if (sizeReductionRatio > 0.7) {
optimizeLevel = 1;
} else if (sizeReductionRatio > 0.5) {
optimizeLevel = 2;
} else if (sizeReductionRatio > 0.35) {
optimizeLevel = 3;
} else { } else {
System.out.println( optimizeLevel = 3;
"Increasing ghostscript optimisation level to " + optimizeLevel);
} }
} }
}
if (expectedOutputSize != null && autoMode) { boolean sizeMet = false;
long outputFileSize = Files.size(tempOutputFile); while (!sizeMet && optimizeLevel <= 4) {
if (outputFileSize > expectedOutputSize) { // Prepare the Ghostscript command
try (PDDocument doc = Loader.loadPDF(new File(tempOutputFile.toString()))) { List<String> command = new ArrayList<>();
long previousFileSize = 0; command.add("gs");
double scaleFactor = 1.0; command.add("-sDEVICE=pdfwrite");
while (true) { command.add("-dCompatibilityLevel=1.4");
for (PDPage page : doc.getPages()) {
PDResources res = page.getResources();
for (COSName name : res.getXObjectNames()) { switch (optimizeLevel) {
PDXObject xobj = res.getXObject(name); case 1:
if (xobj instanceof PDImageXObject) { command.add("-dPDFSETTINGS=/prepress");
PDImageXObject image = (PDImageXObject) xobj; break;
case 2:
command.add("-dPDFSETTINGS=/printer");
break;
case 3:
command.add("-dPDFSETTINGS=/ebook");
break;
case 4:
command.add("-dPDFSETTINGS=/screen");
break;
default:
command.add("-dPDFSETTINGS=/default");
}
// Get the image in BufferedImage format command.add("-dNOPAUSE");
BufferedImage bufferedImage = image.getImage(); command.add("-dQUIET");
command.add("-dBATCH");
command.add("-sOutputFile=" + tempOutputFile.toString());
command.add(tempInputFile.toString());
// Calculate the new dimensions ProcessExecutorResult returnCode =
int newWidth = (int) (bufferedImage.getWidth() * scaleFactor); ProcessExecutor.getInstance(ProcessExecutor.Processes.GHOSTSCRIPT)
int newHeight = (int) (bufferedImage.getHeight() * scaleFactor); .runCommandWithOutputHandling(command);
// If the new dimensions are zero, skip this iteration // Check if file size is within expected size or not auto mode so instantly finish
if (newWidth == 0 || newHeight == 0) { long outputFileSize = Files.size(tempOutputFile);
continue; if (outputFileSize <= expectedOutputSize || !autoMode) {
sizeMet = true;
} else {
// Increase optimization level for next iteration
optimizeLevel++;
if (autoMode && optimizeLevel > 4) {
System.out.println("Skipping level 5 due to bad results in auto mode");
sizeMet = true;
} else {
System.out.println(
"Increasing ghostscript optimisation level to " + optimizeLevel);
}
}
}
if (expectedOutputSize != null && autoMode) {
long outputFileSize = Files.size(tempOutputFile);
byte[] fileBytes = Files.readAllBytes(tempOutputFile);
if (outputFileSize > expectedOutputSize) {
try (PDDocument doc = Loader.loadPDF(fileBytes)) {
long previousFileSize = 0;
double scaleFactorConst = 0.9f;
double scaleFactor = 0.9f;
while (true) {
for (PDPage page : doc.getPages()) {
PDResources res = page.getResources();
if (res != null && res.getXObjectNames() != null) {
for (COSName name : res.getXObjectNames()) {
PDXObject xobj = res.getXObject(name);
if (xobj != null && xobj instanceof PDImageXObject) {
PDImageXObject image = (PDImageXObject) xobj;
// Get the image in BufferedImage format
BufferedImage bufferedImage = image.getImage();
// Calculate the new dimensions
int newWidth =
(int)
(bufferedImage.getWidth()
* scaleFactorConst);
int newHeight =
(int)
(bufferedImage.getHeight()
* scaleFactorConst);
// If the new dimensions are zero, skip this iteration
if (newWidth == 0 || newHeight == 0) {
continue;
}
// Otherwise, proceed with the scaling
Image scaledImage =
bufferedImage.getScaledInstance(
newWidth,
newHeight,
Image.SCALE_SMOOTH);
// Convert the scaled image back to a BufferedImage
BufferedImage scaledBufferedImage =
new BufferedImage(
newWidth,
newHeight,
BufferedImage.TYPE_INT_RGB);
scaledBufferedImage
.getGraphics()
.drawImage(scaledImage, 0, 0, null);
// Compress the scaled image
ByteArrayOutputStream compressedImageStream =
new ByteArrayOutputStream();
ImageIO.write(
scaledBufferedImage,
"jpeg",
compressedImageStream);
byte[] imageBytes = compressedImageStream.toByteArray();
compressedImageStream.close();
PDImageXObject compressedImage =
PDImageXObject.createFromByteArray(
doc,
imageBytes,
image.getCOSObject().toString());
// Replace the image in the resources with the
// compressed
// version
res.put(name, compressedImage);
}
} }
// Otherwise, proceed with the scaling
Image scaledImage =
bufferedImage.getScaledInstance(
newWidth, newHeight, Image.SCALE_SMOOTH);
// Convert the scaled image back to a BufferedImage
BufferedImage scaledBufferedImage =
new BufferedImage(
newWidth,
newHeight,
BufferedImage.TYPE_INT_RGB);
scaledBufferedImage
.getGraphics()
.drawImage(scaledImage, 0, 0, null);
// Compress the scaled image
ByteArrayOutputStream compressedImageStream =
new ByteArrayOutputStream();
ImageIO.write(
scaledBufferedImage, "jpeg", compressedImageStream);
byte[] imageBytes = compressedImageStream.toByteArray();
compressedImageStream.close();
// Convert compressed image back to PDImageXObject
ByteArrayInputStream bais =
new ByteArrayInputStream(imageBytes);
PDImageXObject compressedImage =
PDImageXObject.createFromByteArray(
doc,
imageBytes,
image.getCOSObject().toString());
// Replace the image in the resources with the compressed
// version
res.put(name, compressedImage);
} }
} }
}
// save the document to tempOutputFile again // save the document to tempOutputFile again
doc.save(tempOutputFile.toString()); doc.save(tempOutputFile.toString());
long currentSize = Files.size(tempOutputFile); long currentSize = Files.size(tempOutputFile);
// Check if the overall PDF size is still larger than expectedOutputSize // Check if the overall PDF size is still larger than expectedOutputSize
if (currentSize > expectedOutputSize) { if (currentSize > expectedOutputSize) {
// Log the current file size and scaleFactor // Log the current file size and scaleFactor
System.out.println( System.out.println(
"Current file size: " "Current file size: "
+ FileUtils.byteCountToDisplaySize(currentSize)); + FileUtils.byteCountToDisplaySize(currentSize));
System.out.println("Current scale factor: " + scaleFactor); System.out.println("Current scale factor: " + scaleFactor);
// The file is still too large, reduce scaleFactor and try again // The file is still too large, reduce scaleFactor and try again
scaleFactor *= 0.9; // reduce scaleFactor by 10% scaleFactor *= 0.9f; // reduce scaleFactor by 10%
// Avoid scaleFactor being too small, causing the image to shrink to 0 // Avoid scaleFactor being too small, causing the image to shrink to
if (scaleFactor < 0.2 || previousFileSize == currentSize) { // 0
throw new RuntimeException( if (scaleFactor < 0.2f || previousFileSize == currentSize) {
"Could not reach the desired size without excessively degrading image quality, lowest size recommended is " throw new RuntimeException(
+ FileUtils.byteCountToDisplaySize(currentSize) "Could not reach the desired size without excessively degrading image quality, lowest size recommended is "
+ ", " + FileUtils.byteCountToDisplaySize(currentSize)
+ currentSize + ", "
+ " bytes"); + currentSize
+ " bytes");
}
previousFileSize = currentSize;
} else {
// The file is small enough, break the loop
break;
} }
previousFileSize = currentSize;
} else {
// The file is small enough, break the loop
break;
} }
} }
} }
} }
// Read the optimized PDF file
pdfBytes = Files.readAllBytes(tempOutputFile);
// Check if optimized file is larger than the original
if (pdfBytes.length > inputFileSize) {
// Log the occurrence
logger.warn(
"Optimized file is larger than the original. Returning the original file instead.");
// Read the original file again
pdfBytes = Files.readAllBytes(tempInputFile);
}
} finally {
// Clean up the temporary files
Files.delete(tempInputFile);
Files.delete(tempOutputFile);
} }
// Read the optimized PDF file
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
// Check if optimized file is larger than the original
if (pdfBytes.length > inputFileSize) {
// Log the occurrence
logger.warn(
"Optimized file is larger than the original. Returning the original file instead.");
// Read the original file again
pdfBytes = Files.readAllBytes(tempInputFile);
}
// Clean up the temporary files
Files.delete(tempInputFile);
Files.delete(tempOutputFile);
// Return the optimized PDF as a response // Return the optimized PDF as a response
String outputFilename = String outputFilename =
Filenames.toSimpleFileName(inputFile.getOriginalFilename()) Filenames.toSimpleFileName(inputFile.getOriginalFilename())

View File

@@ -84,6 +84,7 @@ public class ExtractImageScansController {
// Load PDF document // Load PDF document
try (PDDocument document = Loader.loadPDF(form.getFileInput().getBytes())) { try (PDDocument document = Loader.loadPDF(form.getFileInput().getBytes())) {
PDFRenderer pdfRenderer = new PDFRenderer(document); PDFRenderer pdfRenderer = new PDFRenderer(document);
pdfRenderer.setSubsamplingAllowed(true);
int pageCount = document.getNumberOfPages(); int pageCount = document.getNumberOfPages();
images = new ArrayList<>(); images = new ArrayList<>();

View File

@@ -60,6 +60,7 @@ public class FakeScanControllerWIP {
PDDocument document = Loader.loadPDF(inputFile.getBytes()); PDDocument document = Loader.loadPDF(inputFile.getBytes());
PDFRenderer pdfRenderer = new PDFRenderer(document); PDFRenderer pdfRenderer = new PDFRenderer(document);
pdfRenderer.setSubsamplingAllowed(true);
for (int page = 0; page < document.getNumberOfPages(); ++page) { for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage image = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB); BufferedImage image = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
ImageIO.write(image, "png", new File("scanned-" + (page + 1) + ".png")); ImageIO.write(image, "png", new File("scanned-" + (page + 1) + ".png"));

View File

@@ -12,7 +12,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@@ -50,9 +49,6 @@ public class PipelineController {
@PostMapping("/handleData") @PostMapping("/handleData")
public ResponseEntity<byte[]> handleData(@ModelAttribute HandleDataRequest request) public ResponseEntity<byte[]> handleData(@ModelAttribute HandleDataRequest request)
throws JsonMappingException, JsonProcessingException { throws JsonMappingException, JsonProcessingException {
if (!Boolean.TRUE.equals(applicationProperties.getSystem().getEnableAlphaFunctionality())) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
MultipartFile[] files = request.getFileInput(); MultipartFile[] files = request.getFileInput();
String jsonString = request.getJson(); String jsonString = request.getJson();

View File

@@ -83,6 +83,7 @@ public class RedactController {
if (convertPDFToImage) { if (convertPDFToImage) {
PDDocument imageDocument = new PDDocument(); PDDocument imageDocument = new PDDocument();
PDFRenderer pdfRenderer = new PDFRenderer(document); PDFRenderer pdfRenderer = new PDFRenderer(document);
pdfRenderer.setSubsamplingAllowed(true);
for (int page = 0; page < document.getNumberOfPages(); ++page) { for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB); BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
PDPage newPage = new PDPage(new PDRectangle(bim.getWidth(), bim.getHeight())); PDPage newPage = new PDPage(new PDRectangle(bim.getWidth(), bim.getHeight()));

View File

@@ -54,33 +54,32 @@ public class SanitizeController {
boolean removeLinks = request.isRemoveLinks(); boolean removeLinks = request.isRemoveLinks();
boolean removeFonts = request.isRemoveFonts(); boolean removeFonts = request.isRemoveFonts();
try (PDDocument document = Loader.loadPDF(inputFile.getBytes())) { PDDocument document = Loader.loadPDF(inputFile.getBytes());
if (removeJavaScript) { if (removeJavaScript) {
sanitizeJavaScript(document); sanitizeJavaScript(document);
}
if (removeEmbeddedFiles) {
sanitizeEmbeddedFiles(document);
}
if (removeMetadata) {
sanitizeMetadata(document);
}
if (removeLinks) {
sanitizeLinks(document);
}
if (removeFonts) {
sanitizeFonts(document);
}
return WebResponseUtils.pdfDocToWebResponse(
document,
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
.replaceFirst("[.][^.]+$", "")
+ "_sanitized.pdf");
} }
if (removeEmbeddedFiles) {
sanitizeEmbeddedFiles(document);
}
if (removeMetadata) {
sanitizeMetadata(document);
}
if (removeLinks) {
sanitizeLinks(document);
}
if (removeFonts) {
sanitizeFonts(document);
}
return WebResponseUtils.pdfDocToWebResponse(
document,
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
.replaceFirst("[.][^.]+$", "")
+ "_sanitized.pdf");
} }
private void sanitizeJavaScript(PDDocument document) throws IOException { private void sanitizeJavaScript(PDDocument document) throws IOException {

View File

@@ -3,10 +3,14 @@ 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.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import stirling.software.SPDF.model.User; import stirling.software.SPDF.model.User;
public interface UserRepository extends JpaRepository<User, String> { public interface UserRepository extends JpaRepository<User, String> {
Optional<User> findByUsernameIgnoreCase(String username);
Optional<User> findByUsername(String username); Optional<User> findByUsername(String username);
User findByApiKey(String apiKey); User findByApiKey(String apiKey);

View File

@@ -136,6 +136,7 @@ public class GeneralUtils {
int offset = oneBased ? 1 : 0; int offset = oneBased ? 1 : 0;
for (String page : pages) { for (String page : pages) {
if ("all".equalsIgnoreCase(page)) { if ("all".equalsIgnoreCase(page)) {
for (int i = 0; i < totalPages; i++) { for (int i = 0; i < totalPages; i++) {
result.add(i + offset); result.add(i + offset);
} }

View File

@@ -214,6 +214,7 @@ public class PdfUtils {
throws IOException, Exception { throws IOException, Exception {
try (PDDocument document = Loader.loadPDF(inputStream)) { try (PDDocument document = Loader.loadPDF(inputStream)) {
PDFRenderer pdfRenderer = new PDFRenderer(document); PDFRenderer pdfRenderer = new PDFRenderer(document);
pdfRenderer.setSubsamplingAllowed(true);
int pageCount = document.getNumberOfPages(); int pageCount = document.getNumberOfPages();
// Create a ByteArrayOutputStream to save the image(s) to // Create a ByteArrayOutputStream to save the image(s) to

View File

@@ -189,7 +189,11 @@ public class ProcessExecutor {
} }
} }
} else if (exitCode != 0) { } else if (exitCode != 0) {
throw new IOException("Command process failed with exit code " + exitCode); throw new IOException(
"Command process failed with exit code "
+ exitCode
+ "\nLogs: "
+ messages);
} }
} finally { } finally {
semaphore.release(); semaphore.release();

View File

@@ -1,11 +0,0 @@
fileToPDF.fileTypesList=Microsoft Word: (DOC, DOCX, DOT, DOTX) <br> \
Microsoft Excel: (CSV, XLS, XLSX, XLT, XLTX, SLK, DIF) <br> \
Microsoft PowerPoint: (PPT, PPTX) <br> \
OpenDocument Formats: (ODT, OTT, ODS, OTS, ODP, OTP, ODG, OTG) <br> \
Plain Text: (TXT, TEXT, XML) <br> \
Rich Text Format: (RTF) <br> \
Images: (BMP, GIF, JPEG, PNG, TIF, PBM, PGM, PPM, RAS, XBM, XPM, SVG, SVM, WMF) <br> \
HTML: (HTML) <br> \
Lotus Word Pro: (LWP) <br> \
StarOffice formats: (SDA, SDC, SDD, SDW, STC, STD, STI, STW, SXD, SXG, SXI, SXW) <br> \
Other formats: (DBF, FODS, VSD, VOR, VOR3, VOR4, UOP, PCT, PS, PDF)

View File

@@ -17,6 +17,7 @@ true=\u0635\u062D\u064A\u062D
false=\u062E\u0637\u0623 false=\u062E\u0637\u0623
unknown=\u063A\u064A\u0631 \u0645\u0639\u0631\u0648\u0641 unknown=\u063A\u064A\u0631 \u0645\u0639\u0631\u0648\u0641
save=\u062D\u0641\u0638 save=\u062D\u0641\u0638
saveToBrowser=Save to Browser
close=\u0625\u063A\u0644\u0627\u0642 close=\u0625\u063A\u0644\u0627\u0642
filesSelected=الملفات المحددة filesSelected=الملفات المحددة
noFavourites=لم تتم إضافة أي مفضلات noFavourites=لم تتم إضافة أي مفضلات
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found. userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect. incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists. usernameExistsMessage=New Username already exists.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Admin User Control Settings
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=User adminUserSettings.user=User
adminUserSettings.addUser=Add New User adminUserSettings.addUser=Add New User
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roles adminUserSettings.roles=Roles
adminUserSettings.role=Role adminUserSettings.role=Role
adminUserSettings.actions=Actions adminUserSettings.actions=Actions

View File

@@ -17,6 +17,7 @@ true=Вярно
false=Невярно false=Невярно
unknown=Непознат unknown=Непознат
save=Съхранете save=Съхранете
saveToBrowser=Save to Browser
close=Затворете close=Затворете
filesSelected=избрани файлове filesSelected=избрани файлове
noFavourites=Няма добавени любими noFavourites=Няма добавени любими
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Потребителят не е автентикира
userNotFoundMessage=Потребителят не е намерен userNotFoundMessage=Потребителят не е намерен
incorrectPasswordMessage=Текущата парола е неправилна. incorrectPasswordMessage=Текущата парола е неправилна.
usernameExistsMessage=Новият потребител вече съществува. usernameExistsMessage=Новият потребител вече съществува.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Настройки за администраторск
adminUserSettings.admin=Администратор adminUserSettings.admin=Администратор
adminUserSettings.user=Потребител adminUserSettings.user=Потребител
adminUserSettings.addUser=Добавяне на нов потребител adminUserSettings.addUser=Добавяне на нов потребител
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Роли adminUserSettings.roles=Роли
adminUserSettings.role=Роля adminUserSettings.role=Роля
adminUserSettings.actions=Действия adminUserSettings.actions=Действия

View File

@@ -17,6 +17,7 @@ true=Verdader
false=Fals false=Fals
unknown=Desconegut unknown=Desconegut
save=Desa save=Desa
saveToBrowser=Save to Browser
close=Tanca close=Tanca
filesSelected=fitxers seleccionats filesSelected=fitxers seleccionats
noFavourites=No s'ha afegit cap favorit noFavourites=No s'ha afegit cap favorit
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found. userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect. incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists. usernameExistsMessage=New Username already exists.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Usuari Admin Opcions Control
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=Usuari adminUserSettings.user=Usuari
adminUserSettings.addUser=Afegir Usuari adminUserSettings.addUser=Afegir Usuari
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Rols adminUserSettings.roles=Rols
adminUserSettings.role=Rol adminUserSettings.role=Rol
adminUserSettings.actions=Accions adminUserSettings.actions=Accions

View File

@@ -8,7 +8,7 @@ pdfPrompt=PDF auswählen
multiPdfPrompt=PDFs auswählen(2+) multiPdfPrompt=PDFs auswählen(2+)
multiPdfDropPrompt=Wählen Sie alle gewünschten PDFs aus (oder ziehen Sie sie per Drag & Drop hierhin) multiPdfDropPrompt=Wählen Sie alle gewünschten PDFs aus (oder ziehen Sie sie per Drag & Drop hierhin)
imgPrompt=Wählen Sie ein Bild imgPrompt=Wählen Sie ein Bild
genericSubmit=Einreichen genericSubmit=Absenden
processTimeWarning=Achtung: Abhängig von der Dateigröße kann dieser Prozess bis zu einer Minute dauern processTimeWarning=Achtung: Abhängig von der Dateigröße kann dieser Prozess bis zu einer Minute dauern
pageOrderPrompt=Seitenreihenfolge (Geben Sie eine durch Komma getrennte Liste von Seitenzahlen ein): pageOrderPrompt=Seitenreihenfolge (Geben Sie eine durch Komma getrennte Liste von Seitenzahlen ein):
pageSelectionPrompt=Benutzerdefinierte Seitenauswahl (Geben Sie eine durch Kommas getrennte Liste von Seitenzahlen 1,5,6 oder Funktionen wie 2n+1 ein): pageSelectionPrompt=Benutzerdefinierte Seitenauswahl (Geben Sie eine durch Kommas getrennte Liste von Seitenzahlen 1,5,6 oder Funktionen wie 2n+1 ein):
@@ -17,10 +17,11 @@ true=Wahr
false=Falsch false=Falsch
unknown=Unbekannt unknown=Unbekannt
save=Speichern save=Speichern
saveToBrowser=Save to Browser
close=Schließen close=Schließen
filesSelected=Dateien ausgewählt filesSelected=Dateien ausgewählt
noFavourites=Keine Favoriten hinzugefügt noFavourites=Keine Favoriten hinzugefügt
downloadComplete=Download Complete downloadComplete=Download abgeschlossen
bored=Langeweile beim Warten? bored=Langeweile beim Warten?
alphabet=Alphabet alphabet=Alphabet
downloadPdf=PDF herunterladen downloadPdf=PDF herunterladen
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Benutzer nicht authentifiziert.
userNotFoundMessage=Benutzer nicht gefunden. userNotFoundMessage=Benutzer nicht gefunden.
incorrectPasswordMessage=Das Passwort ist falsch. incorrectPasswordMessage=Das Passwort ist falsch.
usernameExistsMessage=Neuer Benutzername existiert bereits. usernameExistsMessage=Neuer Benutzername existiert bereits.
invalidUsernameMessage=Ungültiger Benutzername. Der Benutzername darf nur Buchstaben und Zahlen enthalten.
deleteCurrentUserMessage=Der aktuell angemeldete Benutzer kann nicht gelöscht werden. deleteCurrentUserMessage=Der aktuell angemeldete Benutzer kann nicht gelöscht werden.
deleteUsernameExistsMessage=Der Benutzername existiert nicht und kann nicht gelöscht werden. deleteUsernameExistsMessage=Der Benutzername existiert nicht und kann nicht gelöscht werden.
@@ -71,12 +73,12 @@ pipeline.submitButton=Speichern
###################### ######################
pipelineOptions.header=Pipeline-Konfiguration pipelineOptions.header=Pipeline-Konfiguration
pipelineOptions.pipelineNameLabel=Pipeline-Name pipelineOptions.pipelineNameLabel=Pipeline-Name
pipelineOptions.saveSettings=Save Operation Settings pipelineOptions.saveSettings=Operations-Einstellungen speichern
pipelineOptions.pipelineNamePrompt=Geben Sie hier den Namen der Pipeline ein pipelineOptions.pipelineNamePrompt=Geben Sie hier den Namen der Pipeline ein
pipelineOptions.selectOperation=Vorgang auswählen pipelineOptions.selectOperation=Vorgang auswählen
pipelineOptions.addOperationButton=Vorgang hinzufügen pipelineOptions.addOperationButton=Vorgang hinzufügen
pipelineOptions.pipelineHeader=Pipeline: pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Downloaden pipelineOptions.saveButton=Herunterladen
pipelineOptions.validateButton=Validieren pipelineOptions.validateButton=Validieren
@@ -88,7 +90,7 @@ pipelineOptions.validateButton=Validieren
navbar.convert=Konvertieren navbar.convert=Konvertieren
navbar.security=Sicherheit navbar.security=Sicherheit
navbar.other=Anderes navbar.other=Anderes
navbar.darkmode=Dark Mode navbar.darkmode=Dunkler Modus
navbar.pageOps=Seitenoperationen navbar.pageOps=Seitenoperationen
navbar.settings=Einstellungen navbar.settings=Einstellungen
@@ -110,7 +112,7 @@ settings.accountSettings=Kontoeinstellungen
changeCreds.title=Anmeldeinformationen ändern changeCreds.title=Anmeldeinformationen ändern
changeCreds.header=Aktualisieren Sie Ihre Kontodaten changeCreds.header=Aktualisieren Sie Ihre Kontodaten
changeCreds.changePassword=You are using default login credentials. Please enter a new password changeCreds.changePassword=Sie verwenden die Standard-Zugangsdaten. Bitte geben Sie ein neues Passwort ein.
changeCreds.newUsername=Neuer Benutzername changeCreds.newUsername=Neuer Benutzername
changeCreds.oldPassword=Aktuelles Passwort changeCreds.oldPassword=Aktuelles Passwort
changeCreds.newPassword=Neues Passwort changeCreds.newPassword=Neues Passwort
@@ -131,7 +133,7 @@ account.newPassword=Neues Passwort
account.changePassword=Passwort ändern account.changePassword=Passwort ändern
account.confirmNewPassword=Neues Passwort bestätigen account.confirmNewPassword=Neues Passwort bestätigen
account.signOut=Abmelden account.signOut=Abmelden
account.yourApiKey=Dein API Schlüssel account.yourApiKey=Dein API-Schlüssel
account.syncTitle=Browsereinstellungen mit Konto synchronisieren account.syncTitle=Browsereinstellungen mit Konto synchronisieren
account.settingsCompare=Einstellungen vergleichen: account.settingsCompare=Einstellungen vergleichen:
account.property=Eigenschaft account.property=Eigenschaft
@@ -145,6 +147,7 @@ adminUserSettings.header=Administrator-Benutzerkontrolle
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=Benutzer adminUserSettings.user=Benutzer
adminUserSettings.addUser=Neuen Benutzer hinzufügen adminUserSettings.addUser=Neuen Benutzer hinzufügen
adminUserSettings.usernameInfo=Der Benutzername darf nur Buchstaben und Zahlen enthalten, keine Leerzeichen oder Sonderzeichen.
adminUserSettings.roles=Rollen adminUserSettings.roles=Rollen
adminUserSettings.role=Rolle adminUserSettings.role=Rolle
adminUserSettings.actions=Aktion adminUserSettings.actions=Aktion
@@ -416,9 +419,9 @@ login.title=Anmelden
login.header=Anmelden login.header=Anmelden
login.signin=Anmelden login.signin=Anmelden
login.rememberme=Angemeldet bleiben login.rememberme=Angemeldet bleiben
login.invalid=Ungültiger Benutzername oder Passwort. login.invalid=Benutzername oder Passwort ungültig.
login.locked=Ihr Konto wurde gesperrt. login.locked=Ihr Konto wurde gesperrt.
login.signinTitle=Bitte melden Sie sich an login.signinTitle=Bitte melden Sie sich an.
#auto-redact #auto-redact
@@ -639,17 +642,17 @@ compare.document.2=Dokument 2
compare.submit=Vergleichen compare.submit=Vergleichen
#BookToPDF #BookToPDF
BookToPDF.title=Books and Comics to PDF BookToPDF.title=Bücher und Comics zu PDF
BookToPDF.header=Book to PDF BookToPDF.header=Buch zu PDF
BookToPDF.credit=Uses Calibre BookToPDF.credit=Verwendet Calibre
BookToPDF.submit=Convert BookToPDF.submit=Konvertieren
#PDFToBook #PDFToBook
PDFToBook.title=PDF to Book PDFToBook.title=PDF zu Buch
PDFToBook.header=PDF to Book PDFToBook.header=PDF zu Buch
PDFToBook.selectText.1=Format PDFToBook.selectText.1=Format
PDFToBook.credit=Uses Calibre PDFToBook.credit=Verwendet Calibre
PDFToBook.submit=Convert PDFToBook.submit=Konvertieren
#sign #sign
sign.title=Signieren sign.title=Signieren
@@ -933,15 +936,15 @@ PDFToText.submit=Konvertieren
#PDFToHTML #PDFToHTML
PDFToHTML.title=PDF in HTML PDFToHTML.title=PDF zu HTML
PDFToHTML.header=PDF in HTML PDFToHTML.header=PDF zu HTML
PDFToHTML.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung. PDFToHTML.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
PDFToHTML.submit=Konvertieren PDFToHTML.submit=Konvertieren
#PDFToXML #PDFToXML
PDFToXML.title=PDF in XML PDFToXML.title=PDF zu XML
PDFToXML.header=PDF in XML PDFToXML.header=PDF zu XML
PDFToXML.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung. PDFToXML.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
PDFToXML.submit=Konvertieren PDFToXML.submit=Konvertieren
@@ -987,7 +990,7 @@ split-by-sections.vertical.label=Vertikale Teiler
split-by-sections.horizontal.placeholder=Anzahl horizontaler Teiler eingeben split-by-sections.horizontal.placeholder=Anzahl horizontaler Teiler eingeben
split-by-sections.vertical.placeholder=Anzahl vertikaler Teiler eingeben split-by-sections.vertical.placeholder=Anzahl vertikaler Teiler eingeben
split-by-sections.submit=PDF teilen split-by-sections.submit=PDF teilen
split-by-sections.merge=Merge Into One PDF split-by-sections.merge=In eine PDF zusammenfügen
#licenses #licenses
licenses.nav=Lizenzen licenses.nav=Lizenzen

View File

@@ -17,6 +17,7 @@ true=\u0391\u03BB\u03B7\u03B8\u03AD\u03C2
false=\u039B\u03B1\u03BD\u03B8\u03B1\u03C3\u03BC\u03AD\u03BD\u03BF false=\u039B\u03B1\u03BD\u03B8\u03B1\u03C3\u03BC\u03AD\u03BD\u03BF
unknown=\u0386\u03B3\u03BD\u03C9\u03C3\u03C4\u03BF unknown=\u0386\u03B3\u03BD\u03C9\u03C3\u03C4\u03BF
save=\u0391\u03C0\u03BF\u03B8\u03AE\u03BA\u03B5\u03C5\u03C3\u03B7 save=\u0391\u03C0\u03BF\u03B8\u03AE\u03BA\u03B5\u03C5\u03C3\u03B7
saveToBrowser=Save to Browser
close=\u039A\u03BB\u03B5\u03AF\u03C3\u03B9\u03BC\u03BF close=\u039A\u03BB\u03B5\u03AF\u03C3\u03B9\u03BC\u03BF
filesSelected=\u03B1\u03C1\u03C7\u03B5\u03AF\u03B1 \u03C0\u03BF\u03C5 \u03B5\u03C0\u03B9\u03BB\u03AD\u03C7\u03B8\u03B7\u03BA\u03B1\u03BD filesSelected=\u03B1\u03C1\u03C7\u03B5\u03AF\u03B1 \u03C0\u03BF\u03C5 \u03B5\u03C0\u03B9\u03BB\u03AD\u03C7\u03B8\u03B7\u03BA\u03B1\u03BD
noFavourites=\u039A\u03B1\u03BD\u03AD\u03BD\u03B1 \u03B1\u03B3\u03B1\u03C0\u03AE\u03BC\u03B5\u03BD\u03BF \u03B4\u03B5\u03BD \u03AD\u03C7\u03B5\u03B9 \u03C0\u03C1\u03BF\u03C3\u03C4\u03B5\u03B8\u03B5\u03AF noFavourites=\u039A\u03B1\u03BD\u03AD\u03BD\u03B1 \u03B1\u03B3\u03B1\u03C0\u03AE\u03BC\u03B5\u03BD\u03BF \u03B4\u03B5\u03BD \u03AD\u03C7\u03B5\u03B9 \u03C0\u03C1\u03BF\u03C3\u03C4\u03B5\u03B8\u03B5\u03AF
@@ -53,6 +54,7 @@ notAuthenticatedMessage=\u039F \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7\u03C2 \u03B4
userNotFoundMessage=\u039F \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7\u03C2 \u03B4\u03B5\u03BD \u03B2\u03C1\u03AD\u03B8\u03B7\u03BA\u03B5. userNotFoundMessage=\u039F \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7\u03C2 \u03B4\u03B5\u03BD \u03B2\u03C1\u03AD\u03B8\u03B7\u03BA\u03B5.
incorrectPasswordMessage=\u039F \u03C4\u03C1\u03AD\u03C7\u03C9\u03BD \u03BA\u03C9\u03B4\u03B9\u03BA\u03CC\u03C2 \u03C0\u03C1\u03CC\u03C3\u03B2\u03B1\u03C3\u03B7\u03C2 \u03B5\u03AF\u03BD\u03B1\u03B9 \u03BB\u03B1\u03BD\u03B8\u03B1\u03C3\u03BC\u03AD\u03BD\u03BF\u03C2. incorrectPasswordMessage=\u039F \u03C4\u03C1\u03AD\u03C7\u03C9\u03BD \u03BA\u03C9\u03B4\u03B9\u03BA\u03CC\u03C2 \u03C0\u03C1\u03CC\u03C3\u03B2\u03B1\u03C3\u03B7\u03C2 \u03B5\u03AF\u03BD\u03B1\u03B9 \u03BB\u03B1\u03BD\u03B8\u03B1\u03C3\u03BC\u03AD\u03BD\u03BF\u03C2.
usernameExistsMessage=\u03A4\u03BF \u03BD\u03AD\u03BF \u03CC\u03BD\u03BF\u03BC\u03B1 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7 \u03C5\u03C0\u03AC\u03C1\u03C7\u03B5\u03B9 \u03AE\u03B4\u03B7. usernameExistsMessage=\u03A4\u03BF \u03BD\u03AD\u03BF \u03CC\u03BD\u03BF\u03BC\u03B1 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7 \u03C5\u03C0\u03AC\u03C1\u03C7\u03B5\u03B9 \u03AE\u03B4\u03B7.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=\u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2
adminUserSettings.admin=\u0394\u03B9\u03B1\u03C7\u03B5\u03B9\u03C1\u03B9\u03C3\u03C4\u03AE\u03C2 adminUserSettings.admin=\u0394\u03B9\u03B1\u03C7\u03B5\u03B9\u03C1\u03B9\u03C3\u03C4\u03AE\u03C2
adminUserSettings.user=\u03A7\u03C1\u03AE\u03C3\u03C4\u03B7\u03C2 adminUserSettings.user=\u03A7\u03C1\u03AE\u03C3\u03C4\u03B7\u03C2
adminUserSettings.addUser=\u03A0\u03C1\u03BF\u03C3\u03B8\u03AE\u03BA\u03B7 \u03BD\u03AD\u03BF\u03C5 \u03A7\u03C1\u03AE\u03C3\u03C4\u03B7 adminUserSettings.addUser=\u03A0\u03C1\u03BF\u03C3\u03B8\u03AE\u03BA\u03B7 \u03BD\u03AD\u03BF\u03C5 \u03A7\u03C1\u03AE\u03C3\u03C4\u03B7
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=\u03A1\u03CC\u03BB\u03BF\u03B9 adminUserSettings.roles=\u03A1\u03CC\u03BB\u03BF\u03B9
adminUserSettings.role=\u03A1\u03CC\u03BB\u03BF\u03C2 adminUserSettings.role=\u03A1\u03CC\u03BB\u03BF\u03C2
adminUserSettings.actions=\u0395\u03BD\u03AD\u03C1\u03B3\u03B5\u03B9\u03B5\u03C2 adminUserSettings.actions=\u0395\u03BD\u03AD\u03C1\u03B3\u03B5\u03B9\u03B5\u03C2

View File

@@ -17,6 +17,7 @@ true=True
false=False false=False
unknown=Unknown unknown=Unknown
save=Save save=Save
saveToBrowser=Save to Browser
close=Close close=Close
filesSelected=files selected filesSelected=files selected
noFavourites=No favourites added noFavourites=No favourites added
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found. userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect. incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists. usernameExistsMessage=New Username already exists.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Admin User Control Settings
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=User adminUserSettings.user=User
adminUserSettings.addUser=Add New User adminUserSettings.addUser=Add New User
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roles adminUserSettings.roles=Roles
adminUserSettings.role=Role adminUserSettings.role=Role
adminUserSettings.actions=Actions adminUserSettings.actions=Actions

View File

@@ -17,6 +17,7 @@ true=True
false=False false=False
unknown=Unknown unknown=Unknown
save=Save save=Save
saveToBrowser=Save to Browser
close=Close close=Close
filesSelected=files selected filesSelected=files selected
noFavourites=No favorites added noFavourites=No favorites added
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found. userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect. incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists. usernameExistsMessage=New Username already exists.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Admin User Control Settings
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=User adminUserSettings.user=User
adminUserSettings.addUser=Add New User adminUserSettings.addUser=Add New User
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roles adminUserSettings.roles=Roles
adminUserSettings.role=Role adminUserSettings.role=Role
adminUserSettings.actions=Actions adminUserSettings.actions=Actions

View File

@@ -17,6 +17,7 @@ true=Verdadero
false=Falso false=Falso
unknown=Desconocido unknown=Desconocido
save=Guardar save=Guardar
saveToBrowser=Save to Browser
close=Cerrar close=Cerrar
filesSelected=archivos seleccionados filesSelected=archivos seleccionados
noFavourites=No se agregaron favoritos noFavourites=No se agregaron favoritos
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Usuario no autentificado.
userNotFoundMessage=Usuario no encontrado. userNotFoundMessage=Usuario no encontrado.
incorrectPasswordMessage=La contraseña actual no es correcta. incorrectPasswordMessage=La contraseña actual no es correcta.
usernameExistsMessage=El nuevo nombre de usuario está en uso. usernameExistsMessage=El nuevo nombre de usuario está en uso.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -145,6 +147,7 @@ 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.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roles adminUserSettings.roles=Roles
adminUserSettings.role=Rol adminUserSettings.role=Rol
adminUserSettings.actions=Acciones adminUserSettings.actions=Acciones

View File

@@ -17,6 +17,7 @@ true=Egiazkoa
false=Faltsua false=Faltsua
unknown=Ezezaguna unknown=Ezezaguna
save=Gorde save=Gorde
saveToBrowser=Save to Browser
close=Itxi close=Itxi
filesSelected=Hautatutako fitxategiak filesSelected=Hautatutako fitxategiak
noFavourites=Ez dira gogokoak gehitu noFavourites=Ez dira gogokoak gehitu
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found. userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect. incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists. usernameExistsMessage=New Username already exists.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Admin Erabiltzailearen Ezarpenen Kontrolak
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=Erabiltzaile adminUserSettings.user=Erabiltzaile
adminUserSettings.addUser=Erabiltzaile berria adminUserSettings.addUser=Erabiltzaile berria
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Rolak adminUserSettings.roles=Rolak
adminUserSettings.role=Rol adminUserSettings.role=Rol
adminUserSettings.actions=Ekintzak adminUserSettings.actions=Ekintzak

View File

@@ -17,6 +17,7 @@ true=Vrai
false=Faux false=Faux
unknown=Inconnu unknown=Inconnu
save=Enregistrer save=Enregistrer
saveToBrowser=Save to Browser
close=Fermer close=Fermer
filesSelected=fichiers sélectionnés filesSelected=fichiers sélectionnés
noFavourites=Aucun favori ajouté noFavourites=Aucun favori ajouté
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Utilisateur non authentifié.
userNotFoundMessage=Utilisateur non trouvé. userNotFoundMessage=Utilisateur non trouvé.
incorrectPasswordMessage=Le mot de passe actuel est incorrect. incorrectPasswordMessage=Le mot de passe actuel est incorrect.
usernameExistsMessage=Le nouveau nom d\u2019utilisateur existe déjà. usernameExistsMessage=Le nouveau nom d\u2019utilisateur existe déjà.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -145,6 +147,7 @@ adminUserSettings.header=Administration des paramètres des utilisateurs
adminUserSettings.admin=Administateur adminUserSettings.admin=Administateur
adminUserSettings.user=Utilisateur adminUserSettings.user=Utilisateur
adminUserSettings.addUser=Ajouter un utilisateur adminUserSettings.addUser=Ajouter un utilisateur
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Rôles adminUserSettings.roles=Rôles
adminUserSettings.role=Rôle adminUserSettings.role=Rôle
adminUserSettings.actions=Actions adminUserSettings.actions=Actions

View File

@@ -17,6 +17,7 @@ true=सही
false=गलत false=गलत
unknown=अज्ञात unknown=अज्ञात
save=सहेजें save=सहेजें
saveToBrowser=Save to Browser
close=बंद करें close=बंद करें
filesSelected=फ़ाइलें चयनित हैं filesSelected=फ़ाइलें चयनित हैं
noFavourites=कोई पसंदीदा जोड़ा नहीं गया है noFavourites=कोई पसंदीदा जोड़ा नहीं गया है
@@ -53,6 +54,7 @@ notAuthenticatedMessage=उपयोगकर्ता प्रमाणित
userNotFoundMessage=उपयोगकर्ता नहीं मिला। userNotFoundMessage=उपयोगकर्ता नहीं मिला।
incorrectPasswordMessage=वर्तमान पासवर्ड गलत है। incorrectPasswordMessage=वर्तमान पासवर्ड गलत है।
usernameExistsMessage=नया उपयोगकर्ता नाम पहले से मौजूद है। usernameExistsMessage=नया उपयोगकर्ता नाम पहले से मौजूद है।
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=व्यवस्थापक उपयोगकर्
adminUserSettings.admin=व्यवस्थापक adminUserSettings.admin=व्यवस्थापक
adminUserSettings.user=उपयोगकर्ता adminUserSettings.user=उपयोगकर्ता
adminUserSettings.addUser=नया उपयोगकर्ता जोड़ें adminUserSettings.addUser=नया उपयोगकर्ता जोड़ें
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=रोल्स adminUserSettings.roles=रोल्स
adminUserSettings.role=रोल adminUserSettings.role=रोल
adminUserSettings.actions=क्रियाएँ adminUserSettings.actions=क्रियाएँ

View File

@@ -17,6 +17,7 @@ true=Igaz
false=Hamis false=Hamis
unknown=Ismeretlen unknown=Ismeretlen
save=Mentés save=Mentés
saveToBrowser=Save to Browser
close=Bezárás close=Bezárás
filesSelected=kiválasztott fájlok filesSelected=kiválasztott fájlok
noFavourites=Nincs hozzáadva kedvenc noFavourites=Nincs hozzáadva kedvenc
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Felhasználó nincs hitelesítve.
userNotFoundMessage=A felhasználó nem található. userNotFoundMessage=A felhasználó nem található.
incorrectPasswordMessage=A jelenlegi jelszó helytelen. incorrectPasswordMessage=A jelenlegi jelszó helytelen.
usernameExistsMessage=Az új felhasználónév már létezik. usernameExistsMessage=Az új felhasználónév már létezik.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Adminisztrátori Felhasználói Vezérlési Beállítá
adminUserSettings.admin=Adminisztrátor adminUserSettings.admin=Adminisztrátor
adminUserSettings.user=Felhasználó adminUserSettings.user=Felhasználó
adminUserSettings.addUser=Új felhasználó hozzáadása adminUserSettings.addUser=Új felhasználó hozzáadása
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Szerepek adminUserSettings.roles=Szerepek
adminUserSettings.role=Szerep adminUserSettings.role=Szerep
adminUserSettings.actions=Műveletek adminUserSettings.actions=Műveletek

View File

@@ -17,6 +17,7 @@ true=Benar
false=Salah false=Salah
unknown=Tidak diketahui unknown=Tidak diketahui
save=Simpan save=Simpan
saveToBrowser=Save to Browser
close=Tutup close=Tutup
filesSelected=berkas dipilih filesSelected=berkas dipilih
noFavourites=Tidak ada favorit yang ditambahkan noFavourites=Tidak ada favorit yang ditambahkan
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Pengguna tidak ter-autentikasi.
userNotFoundMessage=Pengguna tidak ditemukan. userNotFoundMessage=Pengguna tidak ditemukan.
incorrectPasswordMessage=Kata sandi saat ini salah. incorrectPasswordMessage=Kata sandi saat ini salah.
usernameExistsMessage=Nama pengguna baru sudah ada. usernameExistsMessage=Nama pengguna baru sudah ada.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Pengaturan Kontrol Admin
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=Pengguna adminUserSettings.user=Pengguna
adminUserSettings.addUser=Tambahkan Pengguna Baru adminUserSettings.addUser=Tambahkan Pengguna Baru
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Peran adminUserSettings.roles=Peran
adminUserSettings.role=Peran adminUserSettings.role=Peran
adminUserSettings.actions=Tindakan adminUserSettings.actions=Tindakan

View File

@@ -17,6 +17,7 @@ true=Vero
false=Falso false=Falso
unknown=Sconosciuto unknown=Sconosciuto
save=Salva save=Salva
saveToBrowser=Save to Browser
close=Chiudi close=Chiudi
filesSelected=file selezionati filesSelected=file selezionati
noFavourites=Nessun preferito noFavourites=Nessun preferito
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Utente non autenticato.
userNotFoundMessage=Utente non trovato. userNotFoundMessage=Utente non trovato.
incorrectPasswordMessage=La password attuale non è corretta. incorrectPasswordMessage=La password attuale non è corretta.
usernameExistsMessage=Il nuovo nome utente esiste già. usernameExistsMessage=Il nuovo nome utente esiste già.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Impossibile eliminare l'utente attualmente connesso. deleteCurrentUserMessage=Impossibile eliminare l'utente attualmente connesso.
deleteUsernameExistsMessage=Il nome utente non esiste e non può essere eliminato. deleteUsernameExistsMessage=Il nome utente non esiste e non può essere eliminato.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=Il nome utente non esiste e non può essere eliminat
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Caricamento personalizzato pipeline.uploadButton=Caricamento personalizzato
pipeline.configureButton=Configura pipeline.configureButton=Configura
pipeline.defaultOption=Personalizzato pipeline.defaultOption=Personalizzato
@@ -145,6 +147,7 @@ adminUserSettings.header=Impostazioni di controllo utente amministratore
adminUserSettings.admin=Amministratore adminUserSettings.admin=Amministratore
adminUserSettings.user=Utente adminUserSettings.user=Utente
adminUserSettings.addUser=Aggiungi un nuovo Utente adminUserSettings.addUser=Aggiungi un nuovo Utente
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Ruoli adminUserSettings.roles=Ruoli
adminUserSettings.role=Ruolo adminUserSettings.role=Ruolo
adminUserSettings.actions=Azioni adminUserSettings.actions=Azioni

View File

@@ -17,6 +17,7 @@ true=True
false=False false=False
unknown=不明 unknown=不明
save=保存 save=保存
saveToBrowser=Save to Browser
close=閉じる close=閉じる
filesSelected=選択されたファイル filesSelected=選択されたファイル
noFavourites=お気に入りはありません noFavourites=お気に入りはありません
@@ -53,6 +54,7 @@ notAuthenticatedMessage=ユーザーが認証されていません。
userNotFoundMessage=ユーザーが見つかりません。 userNotFoundMessage=ユーザーが見つかりません。
incorrectPasswordMessage=現在のパスワードが正しくありません。 incorrectPasswordMessage=現在のパスワードが正しくありません。
usernameExistsMessage=新しいユーザー名はすでに存在します。 usernameExistsMessage=新しいユーザー名はすでに存在します。
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -145,6 +147,7 @@ adminUserSettings.header=管理者ユーザー制御設定
adminUserSettings.admin=管理者 adminUserSettings.admin=管理者
adminUserSettings.user=ユーザー adminUserSettings.user=ユーザー
adminUserSettings.addUser=新しいユーザを追加 adminUserSettings.addUser=新しいユーザを追加
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=役割 adminUserSettings.roles=役割
adminUserSettings.role=役割 adminUserSettings.role=役割
adminUserSettings.actions=アクション adminUserSettings.actions=アクション

View File

@@ -17,6 +17,7 @@ true=참
false=거짓 false=거짓
unknown=알 수 없음 unknown=알 수 없음
save=저장 save=저장
saveToBrowser=Save to Browser
close=닫기 close=닫기
filesSelected=개 파일 선택됨 filesSelected=개 파일 선택됨
noFavourites=즐겨찾기 없음 noFavourites=즐겨찾기 없음
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=사용자를 찾을 수 없습니다. userNotFoundMessage=사용자를 찾을 수 없습니다.
incorrectPasswordMessage=현재 비밀번호가 틀립니다. incorrectPasswordMessage=현재 비밀번호가 틀립니다.
usernameExistsMessage=새 사용자명이 이미 존재합니다. usernameExistsMessage=새 사용자명이 이미 존재합니다.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=사용자 관리
adminUserSettings.admin=관리자 adminUserSettings.admin=관리자
adminUserSettings.user=사용자 adminUserSettings.user=사용자
adminUserSettings.addUser=새 사용자 추가 adminUserSettings.addUser=새 사용자 추가
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=역할 adminUserSettings.roles=역할
adminUserSettings.role=역할 adminUserSettings.role=역할
adminUserSettings.actions=동작 adminUserSettings.actions=동작

View File

@@ -17,6 +17,7 @@ true=Waar
false=Onwaar false=Onwaar
unknown=Onbekend unknown=Onbekend
save=Opslaan save=Opslaan
saveToBrowser=Save to Browser
close=Sluiten close=Sluiten
filesSelected=Bestanden geselecteerd filesSelected=Bestanden geselecteerd
noFavourites=Geen favorieten toegevoegd noFavourites=Geen favorieten toegevoegd
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Gebruiker niet ingelogd.
userNotFoundMessage=Gebruiker niet gevonden. userNotFoundMessage=Gebruiker niet gevonden.
incorrectPasswordMessage=Huidige wachtwoord is onjuist. incorrectPasswordMessage=Huidige wachtwoord is onjuist.
usernameExistsMessage=Nieuwe gebruikersnaam bestaat al. usernameExistsMessage=Nieuwe gebruikersnaam bestaat al.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -145,6 +147,7 @@ adminUserSettings.header=Beheer gebruikers
adminUserSettings.admin=Beheerder adminUserSettings.admin=Beheerder
adminUserSettings.user=Gebruiker adminUserSettings.user=Gebruiker
adminUserSettings.addUser=Voeg nieuwe gebruiker toe adminUserSettings.addUser=Voeg nieuwe gebruiker toe
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Rollen adminUserSettings.roles=Rollen
adminUserSettings.role=Rol adminUserSettings.role=Rol
adminUserSettings.actions=Acties adminUserSettings.actions=Acties

View File

@@ -17,6 +17,7 @@ true=Tak
false=Nie false=Nie
unknown=Nieznany unknown=Nieznany
save=Zapisz save=Zapisz
saveToBrowser=Save to Browser
close=Zamknij close=Zamknij
filesSelected=wybrane pliki filesSelected=wybrane pliki
noFavourites=Nie dodano ulubionych noFavourites=Nie dodano ulubionych
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found. userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect. incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists. usernameExistsMessage=New Username already exists.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Admin User Control Settings
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=User adminUserSettings.user=User
adminUserSettings.addUser=Add New User adminUserSettings.addUser=Add New User
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roles adminUserSettings.roles=Roles
adminUserSettings.role=Role adminUserSettings.role=Role
adminUserSettings.actions=Actions adminUserSettings.actions=Actions

View File

@@ -17,6 +17,7 @@ true=Verdadeiro
false=Falso false=Falso
unknown=Desconhecido unknown=Desconhecido
save=Salvar save=Salvar
saveToBrowser=Save to Browser
close=Fechar close=Fechar
filesSelected=arquivos selecionados filesSelected=arquivos selecionados
noFavourites=Nenhum favorito adicionado noFavourites=Nenhum favorito adicionado
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found. userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect. incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists. usernameExistsMessage=New Username already exists.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Admin User Control Settings
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=User adminUserSettings.user=User
adminUserSettings.addUser=Add New User adminUserSettings.addUser=Add New User
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roles adminUserSettings.roles=Roles
adminUserSettings.role=Role adminUserSettings.role=Role
adminUserSettings.actions=Actions adminUserSettings.actions=Actions

View File

@@ -17,6 +17,7 @@ true=Verdadeiro
false=Falso false=Falso
unknown=Desconhecido unknown=Desconhecido
save=Salvar save=Salvar
saveToBrowser=Save to Browser
close=Fechar close=Fechar
filesSelected=Ficheiros Selecionados filesSelected=Ficheiros Selecionados
noFavourites=Nenhum favorito adicionado noFavourites=Nenhum favorito adicionado
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Utilizador não autenticado.
userNotFoundMessage=Utilizador inexistente. userNotFoundMessage=Utilizador inexistente.
incorrectPasswordMessage=Senha incorreta. incorrectPasswordMessage=Senha incorreta.
usernameExistsMessage=Esse utilizador já existe. usernameExistsMessage=Esse utilizador já existe.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Carregar personalizado pipeline.uploadButton=Carregar personalizado
pipeline.configureButton=Configurar pipeline.configureButton=Configurar
pipeline.defaultOption=Personalizar pipeline.defaultOption=Personalizar
@@ -145,6 +147,7 @@ adminUserSettings.header=Admin User Control Settings
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=User adminUserSettings.user=User
adminUserSettings.addUser=Add New User adminUserSettings.addUser=Add New User
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roles adminUserSettings.roles=Roles
adminUserSettings.role=Role adminUserSettings.role=Role
adminUserSettings.actions=Actions adminUserSettings.actions=Actions

View File

@@ -17,6 +17,7 @@ true=Adevărat
false=Fals false=Fals
unknown=Necunoscut unknown=Necunoscut
save=Salvează save=Salvează
saveToBrowser=Save to Browser
close=Închide close=Închide
filesSelected=fișiere selectate filesSelected=fișiere selectate
noFavourites=Niciun favorit adăugat noFavourites=Niciun favorit adăugat
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found. userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect. incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists. usernameExistsMessage=New Username already exists.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Admin User Control Settings
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=User adminUserSettings.user=User
adminUserSettings.addUser=Add New User adminUserSettings.addUser=Add New User
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roles adminUserSettings.roles=Roles
adminUserSettings.role=Role adminUserSettings.role=Role
adminUserSettings.actions=Actions adminUserSettings.actions=Actions

View File

@@ -17,6 +17,7 @@ true=Истина
false=Ложь false=Ложь
unknown=Неизвестно unknown=Неизвестно
save=Сохранить save=Сохранить
saveToBrowser=Save to Browser
close=Закрыть close=Закрыть
filesSelected=файлов выбрано filesSelected=файлов выбрано
noFavourites=Нет избранного noFavourites=Нет избранного
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found. userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect. incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists. usernameExistsMessage=New Username already exists.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Admin User Control Settings
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=User adminUserSettings.user=User
adminUserSettings.addUser=Add New User adminUserSettings.addUser=Add New User
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roles adminUserSettings.roles=Roles
adminUserSettings.role=Role adminUserSettings.role=Role
adminUserSettings.actions=Actions adminUserSettings.actions=Actions

View File

@@ -17,6 +17,7 @@ true=Tačno
false=Netačno false=Netačno
unknown=Nepoznato unknown=Nepoznato
save=Sačuvaj save=Sačuvaj
saveToBrowser=Save to Browser
close=Zatvori close=Zatvori
filesSelected=odabrani fajlovi filesSelected=odabrani fajlovi
noFavourites=Nema dodatih favorita noFavourites=Nema dodatih favorita
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Korisnik nije autentifikovan.
userNotFoundMessage=Korisnik nije pronađen. userNotFoundMessage=Korisnik nije pronađen.
incorrectPasswordMessage=Trenutna šifra je netačna. incorrectPasswordMessage=Trenutna šifra je netačna.
usernameExistsMessage=Novi korisnik već postoji usernameExistsMessage=Novi korisnik već postoji
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -145,6 +147,7 @@ adminUserSettings.header=Podešavanja kontrole korisnika za administratora
adminUserSettings.admin=Administrator adminUserSettings.admin=Administrator
adminUserSettings.user=Korisnik adminUserSettings.user=Korisnik
adminUserSettings.addUser=Dodaj novog korisnika adminUserSettings.addUser=Dodaj novog korisnika
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Uloge adminUserSettings.roles=Uloge
adminUserSettings.role=Uloga adminUserSettings.role=Uloga
adminUserSettings.actions=Akcije adminUserSettings.actions=Akcije

View File

@@ -17,6 +17,7 @@ true=True
false=Falskt false=Falskt
unknown=Okänt unknown=Okänt
save=Spara save=Spara
saveToBrowser=Save to Browser
close=Stäng close=Stäng
filesSelected=filer valda filesSelected=filer valda
noFavourites=Inga favoriter har lagts till noFavourites=Inga favoriter har lagts till
@@ -53,6 +54,7 @@ notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found. userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect. incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists. usernameExistsMessage=New Username already exists.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=Admin User Control Settings
adminUserSettings.admin=Admin adminUserSettings.admin=Admin
adminUserSettings.user=User adminUserSettings.user=User
adminUserSettings.addUser=Add New User adminUserSettings.addUser=Add New User
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roles adminUserSettings.roles=Roles
adminUserSettings.role=Role adminUserSettings.role=Role
adminUserSettings.actions=Actions adminUserSettings.actions=Actions

View File

@@ -17,6 +17,7 @@ true=Doğru
false=Yanlış false=Yanlış
unknown=Bilinmeyen unknown=Bilinmeyen
save=Kaydet save=Kaydet
saveToBrowser=Save to Browser
close=Kapat close=Kapat
filesSelected=dosya seçildi filesSelected=dosya seçildi
noFavourites=Favori eklenmedi noFavourites=Favori eklenmedi
@@ -53,6 +54,7 @@ notAuthenticatedMessage=Kullanıcı doğrulanmadı.
userNotFoundMessage=Kullanıcı bulunamadı. 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=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ 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.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=Roller adminUserSettings.roles=Roller
adminUserSettings.role=Rol adminUserSettings.role=Rol
adminUserSettings.actions=Eylemler adminUserSettings.actions=Eylemler

View File

@@ -17,6 +17,7 @@ true=对
false= false=
unknown=未知 unknown=未知
save=保存 save=保存
saveToBrowser=Save to Browser
close=关闭 close=关闭
filesSelected=选中的文件 filesSelected=选中的文件
noFavourites=没有添加收藏夹 noFavourites=没有添加收藏夹
@@ -53,6 +54,7 @@ notAuthenticatedMessage=用户未经过身份验证。
userNotFoundMessage=未找到用户。 userNotFoundMessage=未找到用户。
incorrectPasswordMessage=当前密码不正确。 incorrectPasswordMessage=当前密码不正确。
usernameExistsMessage=新用户名已存在。 usernameExistsMessage=新用户名已存在。
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=管理员用户控制设置
adminUserSettings.admin=管理员 adminUserSettings.admin=管理员
adminUserSettings.user=用户 adminUserSettings.user=用户
adminUserSettings.addUser=添加新用户 adminUserSettings.addUser=添加新用户
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=角色 adminUserSettings.roles=角色
adminUserSettings.role=角色 adminUserSettings.role=角色
adminUserSettings.actions=操作 adminUserSettings.actions=操作

View File

@@ -17,6 +17,7 @@ true=是
false= false=
unknown=未知 unknown=未知
save=儲存 save=儲存
saveToBrowser=Save to Browser
close=關閉 close=關閉
filesSelected=已選擇的檔案 filesSelected=已選擇的檔案
noFavourites=未新增收藏 noFavourites=未新增收藏
@@ -53,6 +54,7 @@ notAuthenticatedMessage=使用者未認證。
userNotFoundMessage=找不到使用者。 userNotFoundMessage=找不到使用者。
incorrectPasswordMessage=目前密碼不正確。 incorrectPasswordMessage=目前密碼不正確。
usernameExistsMessage=新使用者名稱已存在。 usernameExistsMessage=新使用者名稱已存在。
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
@@ -60,7 +62,7 @@ deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Alpha) pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure pipeline.configureButton=Configure
pipeline.defaultOption=Custom pipeline.defaultOption=Custom
@@ -145,6 +147,7 @@ adminUserSettings.header=管理使用者控制設定
adminUserSettings.admin=管理員 adminUserSettings.admin=管理員
adminUserSettings.user=使用者 adminUserSettings.user=使用者
adminUserSettings.addUser=新增使用者 adminUserSettings.addUser=新增使用者
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.roles=角色 adminUserSettings.roles=角色
adminUserSettings.role=角色 adminUserSettings.role=角色
adminUserSettings.actions=操作 adminUserSettings.actions=操作

View File

@@ -3,69 +3,69 @@
{ {
"moduleName": "ch.qos.logback:logback-classic", "moduleName": "ch.qos.logback:logback-classic",
"moduleUrl": "http://www.qos.ch", "moduleUrl": "http://www.qos.ch",
"moduleVersion": "1.4.14", "moduleVersion": "1.5.3",
"moduleLicense": "GNU Lesser General Public License", "moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" "moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
}, },
{ {
"moduleName": "ch.qos.logback:logback-core", "moduleName": "ch.qos.logback:logback-core",
"moduleUrl": "http://www.qos.ch", "moduleUrl": "http://www.qos.ch",
"moduleVersion": "1.4.14", "moduleVersion": "1.5.3",
"moduleLicense": "GNU Lesser General Public License", "moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" "moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
}, },
{ {
"moduleName": "com.fasterxml.jackson.core:jackson-annotations", "moduleName": "com.fasterxml.jackson.core:jackson-annotations",
"moduleUrl": "https://github.com/FasterXML/jackson", "moduleUrl": "https://github.com/FasterXML/jackson",
"moduleVersion": "2.15.3", "moduleVersion": "2.15.4",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "com.fasterxml.jackson.core:jackson-core", "moduleName": "com.fasterxml.jackson.core:jackson-core",
"moduleUrl": "https://github.com/FasterXML/jackson-core", "moduleUrl": "https://github.com/FasterXML/jackson-core",
"moduleVersion": "2.15.3", "moduleVersion": "2.15.4",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "com.fasterxml.jackson.core:jackson-databind", "moduleName": "com.fasterxml.jackson.core:jackson-databind",
"moduleUrl": "https://github.com/FasterXML/jackson", "moduleUrl": "https://github.com/FasterXML/jackson",
"moduleVersion": "2.15.3", "moduleVersion": "2.15.4",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", "moduleName": "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml",
"moduleUrl": "https://github.com/FasterXML/jackson-dataformats-text", "moduleUrl": "https://github.com/FasterXML/jackson-dataformats-text",
"moduleVersion": "2.15.3", "moduleVersion": "2.15.4",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jdk8", "moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jdk8",
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8", "moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8",
"moduleVersion": "2.15.3", "moduleVersion": "2.15.4",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", "moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jsr310",
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310", "moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310",
"moduleVersion": "2.15.3", "moduleVersion": "2.15.4",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "com.fasterxml.jackson.module:jackson-module-parameter-names", "moduleName": "com.fasterxml.jackson.module:jackson-module-parameter-names",
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names", "moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names",
"moduleVersion": "2.15.3", "moduleVersion": "2.15.4",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "com.fasterxml.jackson:jackson-bom", "moduleName": "com.fasterxml.jackson:jackson-bom",
"moduleVersion": "2.15.3" "moduleVersion": "2.15.4"
}, },
{ {
"moduleName": "com.fasterxml:classmate", "moduleName": "com.fasterxml:classmate",
@@ -74,6 +74,13 @@
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{
"moduleName": "com.fathzer:javaluator",
"moduleUrl": "http://javaluator.fathzer.com",
"moduleVersion": "3.0.3",
"moduleLicense": "GNU Lesser General Public License v3 (LGPL-v3)",
"moduleLicenseUrl": "http://www.gnu.org/licenses/lgpl-3.0.html"
},
{ {
"moduleName": "com.github.vladimir-bukhtoyarov:bucket4j-core", "moduleName": "com.github.vladimir-bukhtoyarov:bucket4j-core",
"moduleUrl": "http://github.com/vladimir-bukhtoyarov/bucket4j/bucket4j-core", "moduleUrl": "http://github.com/vladimir-bukhtoyarov/bucket4j/bucket4j-core",
@@ -84,7 +91,7 @@
{ {
"moduleName": "com.google.zxing:core", "moduleName": "com.google.zxing:core",
"moduleUrl": "https://github.com/zxing/zxing/core", "moduleUrl": "https://github.com/zxing/zxing/core",
"moduleVersion": "3.5.2", "moduleVersion": "3.5.3",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
@@ -221,28 +228,28 @@
{ {
"moduleName": "io.micrometer:micrometer-commons", "moduleName": "io.micrometer:micrometer-commons",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer", "moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.12.2", "moduleVersion": "1.12.3",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "io.micrometer:micrometer-core", "moduleName": "io.micrometer:micrometer-core",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer", "moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.12.2", "moduleVersion": "1.12.3",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "io.micrometer:micrometer-jakarta9", "moduleName": "io.micrometer:micrometer-jakarta9",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer", "moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.12.2", "moduleVersion": "1.12.3",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "io.micrometer:micrometer-observation", "moduleName": "io.micrometer:micrometer-observation",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer", "moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.12.2", "moduleVersion": "1.12.3",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
@@ -324,7 +331,7 @@
}, },
{ {
"moduleName": "net.bytebuddy:byte-buddy", "moduleName": "net.bytebuddy:byte-buddy",
"moduleVersion": "1.14.11", "moduleVersion": "1.14.12",
"moduleLicense": "Apache License, Version 2.0", "moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
@@ -399,21 +406,21 @@
{ {
"moduleName": "org.apache.tomcat.embed:tomcat-embed-core", "moduleName": "org.apache.tomcat.embed:tomcat-embed-core",
"moduleUrl": "https://tomcat.apache.org/", "moduleUrl": "https://tomcat.apache.org/",
"moduleVersion": "10.1.18", "moduleVersion": "10.1.19",
"moduleLicense": "Eclipse Public License - v 2.0", "moduleLicense": "Eclipse Public License - v 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt" "moduleLicenseUrl": "https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt"
}, },
{ {
"moduleName": "org.apache.tomcat.embed:tomcat-embed-el", "moduleName": "org.apache.tomcat.embed:tomcat-embed-el",
"moduleUrl": "https://tomcat.apache.org/", "moduleUrl": "https://tomcat.apache.org/",
"moduleVersion": "10.1.18", "moduleVersion": "10.1.19",
"moduleLicense": "Apache License, Version 2.0", "moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
{ {
"moduleName": "org.apache.tomcat.embed:tomcat-embed-websocket", "moduleName": "org.apache.tomcat.embed:tomcat-embed-websocket",
"moduleUrl": "https://tomcat.apache.org/", "moduleUrl": "https://tomcat.apache.org/",
"moduleVersion": "10.1.18", "moduleVersion": "10.1.19",
"moduleLicense": "Apache License, Version 2.0", "moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },
@@ -522,7 +529,7 @@
{ {
"moduleName": "org.hibernate.orm:hibernate-core", "moduleName": "org.hibernate.orm:hibernate-core",
"moduleUrl": "https://www.hibernate.org/orm/6.4", "moduleUrl": "https://www.hibernate.org/orm/6.4",
"moduleVersion": "6.4.1.Final", "moduleVersion": "6.4.4.Final",
"moduleLicense": "GNU Library General Public License v2.1 or later", "moduleLicense": "GNU Library General Public License v2.1 or later",
"moduleLicenseUrl": "https://www.opensource.org/licenses/LGPL-2.1" "moduleLicenseUrl": "https://www.opensource.org/licenses/LGPL-2.1"
}, },
@@ -536,48 +543,48 @@
{ {
"moduleName": "org.junit.jupiter:junit-jupiter", "moduleName": "org.junit.jupiter:junit-jupiter",
"moduleUrl": "https://junit.org/junit5/", "moduleUrl": "https://junit.org/junit5/",
"moduleVersion": "5.10.1", "moduleVersion": "5.10.2",
"moduleLicense": "Eclipse Public License v2.0", "moduleLicense": "Eclipse Public License v2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html" "moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html"
}, },
{ {
"moduleName": "org.junit.jupiter:junit-jupiter-api", "moduleName": "org.junit.jupiter:junit-jupiter-api",
"moduleUrl": "https://junit.org/junit5/", "moduleUrl": "https://junit.org/junit5/",
"moduleVersion": "5.10.1", "moduleVersion": "5.10.2",
"moduleLicense": "Eclipse Public License v2.0", "moduleLicense": "Eclipse Public License v2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html" "moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html"
}, },
{ {
"moduleName": "org.junit.jupiter:junit-jupiter-engine", "moduleName": "org.junit.jupiter:junit-jupiter-engine",
"moduleUrl": "https://junit.org/junit5/", "moduleUrl": "https://junit.org/junit5/",
"moduleVersion": "5.10.1", "moduleVersion": "5.10.2",
"moduleLicense": "Eclipse Public License v2.0", "moduleLicense": "Eclipse Public License v2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html" "moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html"
}, },
{ {
"moduleName": "org.junit.jupiter:junit-jupiter-params", "moduleName": "org.junit.jupiter:junit-jupiter-params",
"moduleUrl": "https://junit.org/junit5/", "moduleUrl": "https://junit.org/junit5/",
"moduleVersion": "5.10.1", "moduleVersion": "5.10.2",
"moduleLicense": "Eclipse Public License v2.0", "moduleLicense": "Eclipse Public License v2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html" "moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html"
}, },
{ {
"moduleName": "org.junit.platform:junit-platform-commons", "moduleName": "org.junit.platform:junit-platform-commons",
"moduleUrl": "https://junit.org/junit5/", "moduleUrl": "https://junit.org/junit5/",
"moduleVersion": "1.10.1", "moduleVersion": "1.10.2",
"moduleLicense": "Eclipse Public License v2.0", "moduleLicense": "Eclipse Public License v2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html" "moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html"
}, },
{ {
"moduleName": "org.junit.platform:junit-platform-engine", "moduleName": "org.junit.platform:junit-platform-engine",
"moduleUrl": "https://junit.org/junit5/", "moduleUrl": "https://junit.org/junit5/",
"moduleVersion": "1.10.1", "moduleVersion": "1.10.2",
"moduleLicense": "Eclipse Public License v2.0", "moduleLicense": "Eclipse Public License v2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html" "moduleLicenseUrl": "https://www.eclipse.org/legal/epl-v20.html"
}, },
{ {
"moduleName": "org.junit:junit-bom", "moduleName": "org.junit:junit-bom",
"moduleVersion": "5.10.1" "moduleVersion": "5.10.2"
}, },
{ {
"moduleName": "org.latencyutils:LatencyUtils", "moduleName": "org.latencyutils:LatencyUtils",
@@ -596,14 +603,14 @@
{ {
"moduleName": "org.slf4j:jul-to-slf4j", "moduleName": "org.slf4j:jul-to-slf4j",
"moduleUrl": "http://www.slf4j.org", "moduleUrl": "http://www.slf4j.org",
"moduleVersion": "2.0.11", "moduleVersion": "2.0.12",
"moduleLicense": "MIT License", "moduleLicense": "MIT License",
"moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php" "moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php"
}, },
{ {
"moduleName": "org.slf4j:slf4j-api", "moduleName": "org.slf4j:slf4j-api",
"moduleUrl": "http://www.slf4j.org", "moduleUrl": "http://www.slf4j.org",
"moduleVersion": "2.0.11", "moduleVersion": "2.0.12",
"moduleLicense": "MIT License", "moduleLicense": "MIT License",
"moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php" "moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php"
}, },
@@ -628,238 +635,238 @@
{ {
"moduleName": "org.springframework.boot:spring-boot", "moduleName": "org.springframework.boot:spring-boot",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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-actuator", "moduleName": "org.springframework.boot:spring-boot-actuator",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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-actuator-autoconfigure", "moduleName": "org.springframework.boot:spring-boot-actuator-autoconfigure",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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-autoconfigure", "moduleName": "org.springframework.boot:spring-boot-autoconfigure",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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-devtools", "moduleName": "org.springframework.boot:spring-boot-devtools",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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", "moduleName": "org.springframework.boot:spring-boot-starter",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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-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.2.2", "moduleVersion": "3.2.3",
"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-aop", "moduleName": "org.springframework.boot:spring-boot-starter-aop",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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-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.2.2", "moduleVersion": "3.2.3",
"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-jdbc", "moduleName": "org.springframework.boot:spring-boot-starter-jdbc",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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-json", "moduleName": "org.springframework.boot:spring-boot-starter-json",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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-logging", "moduleName": "org.springframework.boot:spring-boot-starter-logging",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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.2.2", "moduleVersion": "3.2.3",
"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.2.2", "moduleVersion": "3.2.3",
"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-tomcat", "moduleName": "org.springframework.boot:spring-boot-starter-tomcat",
"moduleUrl": "https://spring.io/projects/spring-boot", "moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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.2.2", "moduleVersion": "3.2.3",
"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.data:spring-data-commons", "moduleName": "org.springframework.data:spring-data-commons",
"moduleUrl": "https://spring.io/projects/spring-data", "moduleUrl": "https://spring.io/projects/spring-data",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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.data:spring-data-jpa", "moduleName": "org.springframework.data:spring-data-jpa",
"moduleUrl": "https://projects.spring.io/spring-data-jpa", "moduleUrl": "https://projects.spring.io/spring-data-jpa",
"moduleVersion": "3.2.2", "moduleVersion": "3.2.3",
"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.security:spring-security-config", "moduleName": "org.springframework.security:spring-security-config",
"moduleUrl": "https://spring.io/projects/spring-security", "moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.2.1", "moduleVersion": "6.2.2",
"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.security:spring-security-core", "moduleName": "org.springframework.security:spring-security-core",
"moduleUrl": "https://spring.io/projects/spring-security", "moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.2.1", "moduleVersion": "6.2.2",
"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.security:spring-security-crypto", "moduleName": "org.springframework.security:spring-security-crypto",
"moduleUrl": "https://spring.io/projects/spring-security", "moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.2.1", "moduleVersion": "6.2.2",
"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.security:spring-security-web", "moduleName": "org.springframework.security:spring-security-web",
"moduleUrl": "https://spring.io/projects/spring-security", "moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.2.1", "moduleVersion": "6.2.2",
"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:spring-aop", "moduleName": "org.springframework:spring-aop",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-aspects", "moduleName": "org.springframework:spring-aspects",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-beans", "moduleName": "org.springframework:spring-beans",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-context", "moduleName": "org.springframework:spring-context",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-core", "moduleName": "org.springframework:spring-core",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-expression", "moduleName": "org.springframework:spring-expression",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-jcl", "moduleName": "org.springframework:spring-jcl",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-jdbc", "moduleName": "org.springframework:spring-jdbc",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-orm", "moduleName": "org.springframework:spring-orm",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-tx", "moduleName": "org.springframework:spring-tx",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-web", "moduleName": "org.springframework:spring-web",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.3", "moduleVersion": "6.1.4",
"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:spring-webmvc", "moduleName": "org.springframework:spring-webmvc",
"moduleUrl": "https://github.com/spring-projects/spring-framework", "moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.2", "moduleVersion": "6.1.4",
"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"
}, },

View File

@@ -479,6 +479,31 @@ document.getElementById("addOperationBtn").addEventListener("click", function ()
hideOrShowPipelineHeader(); hideOrShowPipelineHeader();
}); });
function loadBrowserPipelinesIntoDropdown() {
let pipelineSelect = document.getElementById("pipelineSelect");
// Retrieve the current set of option values for comparison
let existingOptions = new Set();
for (let option of pipelineSelect.options) {
existingOptions.add(option.value);
}
// Iterate over all items in localStorage
for (let i = 0; i < localStorage.length; i++) {
let key = localStorage.key(i);
if (key.startsWith("#Pipeline-")) {
let pipelineData = localStorage.getItem(key);
// Check if the data is already in the dropdown
if (!existingOptions.has(pipelineData)) {
let pipelineName = key.replace("#Pipeline-", ""); // Extract pipeline name from the key
let option = new Option(pipelineName, pipelineData); // Use pipeline data as the option value
pipelineSelect.appendChild(option);
}
}
}
}
loadBrowserPipelinesIntoDropdown();
function updateConfigInDropdown() { function updateConfigInDropdown() {
let pipelineSelect = document.getElementById("pipelineSelect"); let pipelineSelect = document.getElementById("pipelineSelect");
let selectedOption = pipelineSelect.options[pipelineSelect.selectedIndex]; let selectedOption = pipelineSelect.options[pipelineSelect.selectedIndex];
@@ -496,13 +521,13 @@ function updateConfigInDropdown() {
} }
var saveBtn = document.getElementById("savePipelineBtn"); var saveBtn = document.getElementById("savePipelineBtn");
var saveBrowserBtn = document.getElementById("saveBrowserPipelineBtn");
// Remove any existing event listeners // Remove any existing event listeners
saveBtn.removeEventListener("click", savePipeline); saveBtn.removeEventListener("click", savePipeline);
saveBrowserBtn.removeEventListener("click", savePipelineToBrowser);
// Add the event listener // Add the event listener
saveBtn.addEventListener("click", savePipeline); saveBtn.addEventListener("click", savePipeline);
console.log("saveBtn", saveBtn); saveBrowserBtn.addEventListener("click", savePipelineToBrowser);
function configToJson() { function configToJson() {
if (!validatePipeline()) { if (!validatePipeline()) {
@@ -537,6 +562,21 @@ function configToJson() {
return JSON.stringify(pipelineConfig, null, 2); return JSON.stringify(pipelineConfig, null, 2);
} }
function savePipelineToBrowser() {
let pipelineConfigJson = configToJson();
if (!pipelineConfigJson) {
console.error("Failed to save pipeline: Invalid configuration");
return;
}
let pipelineName = document.getElementById("pipelineName").value;
if (!pipelineName) {
console.error("Failed to save pipeline: Pipeline name is required");
return;
}
localStorage.setItem("#Pipeline-" +pipelineName, pipelineConfigJson);
console.log("Pipeline configuration saved to localStorage");
}
function savePipeline() { function savePipeline() {
let pipelineConfigJson = configToJson(); let pipelineConfigJson = configToJson();
if (!pipelineConfigJson) { if (!pipelineConfigJson) {

View File

@@ -30,6 +30,9 @@
<div th:if="${param.messageType[0] == 'usernameExists'}" class="alert alert-danger"> <div th:if="${param.messageType[0] == 'usernameExists'}" class="alert alert-danger">
<span th:text="#{usernameExistsMessage}">Default message if not found</span> <span th:text="#{usernameExistsMessage}">Default message if not found</span>
</div> </div>
<div th:if="${param.messageType[0] == 'invalidUsername'}" class="alert alert-danger">
<span th:text="#{invalidUsernameMessage}">Default message if not found</span>
</div>
</th:block> </th:block>
<!-- At the top of the user settings --> <!-- At the top of the user settings -->
<h3 class="text-center"><span th:text="#{welcome} + ' ' + ${username}">User</span>!</h3> <h3 class="text-center"><span th:text="#{welcome} + ' ' + ${username}">User</span>!</h3>

View File

@@ -42,13 +42,14 @@
</table> </table>
<h2 th:text="#{adminUserSettings.addUser}">Add New User</h2> <h2 th:text="#{adminUserSettings.addUser}">Add New User</h2>
<div th:if="${param.messageType != null and param.messageType.size() > 0 and param.messageType[0] == 'usernameExists'}" class="alert alert-danger"> <div th:if="${param.messageType != null and param.messageType.size() > 0 and (param.messageType[0] == 'usernameExists' or param.messageType[0] == 'invalidUsername')}" class="alert alert-danger">
<span th:text="#{usernameExistsMessage}">Default message if not found</span> <span th:if="${param.messageType[0] == 'usernameExists'}" th:text="#{usernameExistsMessage}">Default message if not found</span>
<span th:if="${param.messageType[0] == 'invalidUsername'}" th:text="#{invalidUsernameMessage}">Default message if not found</span>
</div> </div>
<form action="/api/v1/user/admin/saveUser" method="post"> <form action="/api/v1/user/admin/saveUser" method="post">
<div class="mb-3"> <div class="mb-3">
<label for="username" th:text="#{username}">Username</label> <label for="username" th:text="#{username}">Username</label>
<input type="text" class="form-control" name="username" required> <input type="text" class="form-control" name="username" pattern="[a-zA-Z0-9]+" th:title="#{adminUserSettings.usernameInfo}" required>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="password" th:text="#{password}">Password</label> <label for="password" th:text="#{password}">Password</label>

View File

@@ -22,7 +22,17 @@
</form> </form>
<p class="mt-3" th:text="#{fileToPDF.credit}"></p> <p class="mt-3" th:text="#{fileToPDF.credit}"></p>
<p class="mt-3" th:text="#{fileToPDF.supportedFileTypes}"></p> <p class="mt-3" th:text="#{fileToPDF.supportedFileTypes}"></p>
<p th:utext="#{fileToPDF.fileTypesList}"></p> <p>Microsoft Word: (DOC, DOCX, DOT, DOTX)</p>
<p>Microsoft Excel: (CSV, XLS, XLSX, XLT, XLTX, SLK, DIF)</p>
<p>Microsoft PowerPoint: (PPT, PPTX)</p>
<p>OpenDocument Formats: (ODT, OTT, ODS, OTS, ODP, OTP, ODG, OTG)</p>
<p>Plain Text: (TXT, TEXT, XML)</p>
<p>Rich Text Format: (RTF)</p>
<p>Images: (BMP, GIF, JPEG, PNG, TIF, PBM, PGM, PPM, RAS, XBM, XPM, SVG, SVM, WMF)</p>
<p>HTML: (HTML)</p>
<p>Lotus Word Pro: (LWP)</p>
<p>StarOffice: (SDA, SDC, SDD, SDW, STC, STD, STI, STW, SXD, SXG, SXI, SXW)</p>
<p>Other: (DBF, FODS, VSD, VOR, VOR3, VOR4, UOP, PCT, PS, PDF)</p>
<a href="https://help.libreoffice.org/latest/en-US/text/shared/guide/supported_formats.html">https://help.libreoffice.org/latest/en-US/text/shared/guide/supported_formats.html</a> <a href="https://help.libreoffice.org/latest/en-US/text/shared/guide/supported_formats.html">https://help.libreoffice.org/latest/en-US/text/shared/guide/supported_formats.html</a>
</div> </div>
</div> </div>

View File

@@ -22,8 +22,8 @@
<span class="icon-text" th:text="#{home.multiTool.title}"></span> <span class="icon-text" th:text="#{home.multiTool.title}"></span>
</a> </a>
</li> </li>
<li th:if="${@enableAlphaFunctionality}" class="nav-item nav-item-separator"></li> <li class="nav-item nav-item-separator"></li>
<li th:if="${@enableAlphaFunctionality}" class="nav-item"> <li class="nav-item">
<a class="nav-link" href="#" th:href="@{pipeline}" th:classappend="${currentPage}=='pipeline' ? 'active' : ''" th:title="#{home.pipeline.desc}"> <a class="nav-link" href="#" th:href="@{pipeline}" th:classappend="${currentPage}=='pipeline' ? 'active' : ''" th:title="#{home.pipeline.desc}">
<img class="icon" src="images/pipeline.svg" alt="icon"> <img class="icon" src="images/pipeline.svg" alt="icon">
<span class="icon-text" th:text="#{home.pipeline.title}"></span> <span class="icon-text" th:text="#{home.pipeline.title}"></span>

View File

@@ -23,9 +23,8 @@
<br> <br>
<input type="text" id="searchBar" onkeyup="filterCards()" th:placeholder="#{home.searchBar}"> <input type="text" id="searchBar" onkeyup="filterCards()" th:placeholder="#{home.searchBar}">
<div class="features-container"> <div class="features-container">
<th:block th:if="${@enableAlphaFunctionality}">
<div th:replace="~{fragments/card :: card(id='pipeline', cardTitle=#{home.pipeline.title}, cardText=#{home.pipeline.desc}, cardLink='pipeline', svgPath='images/pipeline.svg', tags=#{pipeline.tags})}"></div> <div th:replace="~{fragments/card :: card(id='pipeline', cardTitle=#{home.pipeline.title}, cardText=#{home.pipeline.desc}, cardLink='pipeline', svgPath='images/pipeline.svg', tags=#{pipeline.tags})}"></div>
</th:block>
<div th:replace="~{fragments/card :: card(id='view-pdf', cardTitle=#{home.viewPdf.title}, cardText=#{home.viewPdf.desc}, cardLink='view-pdf', svgPath='images/book-opened.svg', tags=#{viewPdf.tags})}"></div> <div th:replace="~{fragments/card :: card(id='view-pdf', cardTitle=#{home.viewPdf.title}, cardText=#{home.viewPdf.desc}, cardLink='view-pdf', svgPath='images/book-opened.svg', tags=#{viewPdf.tags})}"></div>
<div th:replace="~{fragments/card :: card(id='multi-tool', cardTitle=#{home.multiTool.title}, cardText=#{home.multiTool.desc}, cardLink='multi-tool', svgPath='images/tools.svg', tags=#{multiTool.tags})}"></div> <div th:replace="~{fragments/card :: card(id='multi-tool', cardTitle=#{home.multiTool.title}, cardText=#{home.multiTool.desc}, cardLink='multi-tool', svgPath='images/tools.svg', tags=#{multiTool.tags})}"></div>
<div th:replace="~{fragments/card :: card(id='merge-pdfs', cardTitle=#{home.merge.title}, cardText=#{home.merge.desc}, cardLink='merge-pdfs', svgPath='images/union.svg', tags=#{merge.tags})}"></div> <div th:replace="~{fragments/card :: card(id='merge-pdfs', cardTitle=#{home.merge.title}, cardText=#{home.merge.desc}, cardLink='merge-pdfs', svgPath='images/union.svg', tags=#{merge.tags})}"></div>

View File

@@ -15,8 +15,13 @@
<br /><br /> <br /><br />
<div class="container"> <div class="container">
<div class="row justify-content-center"> <div class="row justify-content-center">
<h1 th:text="#{pipeline.header}"></h1>
<h2 th:text="#{WorkInProgess}"></h2> <div style="text-align: center;">
<h1 th:text="#{pipeline.header}"></h1>
<img src="images/pipeline.svg" alt="icon" style="filter: invert(33%) sepia(100%) saturate(5000%) hue-rotate(183deg) brightness(90%) contrast(100%); width: 100px; height: 100px;">
</div>
<div class="bordered-box"> <div class="bordered-box">
<div class="text-end text-top"> <div class="text-end text-top">
<button id="uploadPipelineBtn" class="btn btn-primary" th:text="#{pipeline.uploadButton}"></button> <button id="uploadPipelineBtn" class="btn btn-primary" th:text="#{pipeline.uploadButton}"></button>
@@ -38,73 +43,12 @@
<div class="element-margin"> <div class="element-margin">
<button class="btn btn-primary" id="submitConfigBtn" th:text="#{pipeline.submitButton}"></button> <button class="btn btn-primary" id="submitConfigBtn" th:text="#{pipeline.submitButton}"></button>
</div> </div>
<a href="https://github.com/Stirling-Tools/Stirling-PDF/blob/main/PipelineFeature.md" target="_blank">Pipeline Help</a>
</br>
<a href="https://github.com/Stirling-Tools/Stirling-PDF/blob/main/FolderScanning.md" target="_blank">Folder Scanning Help</a>
</div> </div>
</div> </div>
<p>Below info is Alpha only, will be removed and hence not translated</p>
<h3>Current Limitations</h3>
<ul>
<li>Cannot have more than one of the same operation</li>
<li>Cannot input additional files via UI</li>
<li>All files and operations run in serial mode</li>
</ul>
<h3>How it Works Notes</h3>
<ul>
<li>Configure the pipeline config file and input files to run files against it</li>
<li>For reuse, download the config file and re-upload it when needed, or place it in /pipeline/defaultWebUIConfigs/ to auto-load in the web UI for all users</li>
</ul>
<h3>How to use pre-load configs in web UI</h3>
<ul>
<li>Download config files</li>
<li>For reuse, download the config file and re-upload it when needed, or place it in /pipeline/defaultWebUIConfigs/ to auto-load in the web UI for all users</li>
</ul>
<h3>Todo</h3>
<ul>
<li>Save to browser/Account</li>
<li>offline folder scan mode checks and testing for unique usecases</li>
<li>Improve operation config settings UI</li>
</ul>
<h2>User Guide for Local Directory Scanning and File Processing</h2>
<h3>Setting Up Watched Folders:</h3>
<p>Create a folder where you want your files to be monitored. This is your 'watched folder'.</p>
<p>The default directory for this is <code>./pipeline/watchedFolders/</code></p>
<p>Place any directories you want to be scanned into this folder, this folder should contain multiple folders each for their own tasks and pipelines.</p>
<h3>Configuring Processing with JSON Files:</h3>
<p>In each directory you want processed (e.g. <code>./pipeline/watchedFolders/officePrinter</code>), include a JSON configuration file.</p>
<p>This JSON file should specify how you want the files in the directory to be handled (e.g., what operations to perform on them) which can be made, configured and downloaded from Stirling-PDF Pipeline interface.</p>
<h3>Automatic Scanning and Processing:</h3>
<p>The system automatically checks the watched folder every minute for new directories and files to process.</p>
<p>When a directory with a valid JSON configuration file is found, it begins processing the files inside as per the configuration.</p>
<h3>Processing Steps:</h3>
<p>Files in each directory are processed according to the instructions in the JSON file.</p>
<p>This might involve file conversions, data filtering, renaming files, etc. If the output of a step is a zip, this zip will be automatically unzipped as it passes to next process.</p>
<h3>Results and Output:</h3>
<p>After processing, the results are saved in a specified output location. This could be a different folder or location as defined in the JSON file or the default location <code>./pipeline/finishedFolders/</code>.</p>
<p>Each processed file is named and organized according to the rules set in the JSON configuration.</p>
<h3>Completion and Cleanup:</h3>
<p>Once processing is complete, the original files in the watched folder's directory are removed.</p>
<p>You can find the processed files in the designated output location.</p>
<h3>Error Handling:</h3>
<p>If there's an error during processing, the system will not delete the original files, allowing you to check and retry if necessary.</p>
<h3>User Interaction:</h3>
<p>As a user, your main tasks are to set up the watched folders, place directories with files for processing, and create the corresponding JSON configuration files.</p>
<p>The system handles the rest, including scanning, processing, and outputting results.</p>
<!-- The Modal --> <!-- The Modal -->
<div class="modal" id="pipelineSettingsModal"> <div class="modal" id="pipelineSettingsModal">
<div class="modal-dialog"> <div class="modal-dialog">
@@ -143,6 +87,7 @@
<!-- Modal footer --> <!-- Modal footer -->
<div class="modal-footer"> <div class="modal-footer">
<button id="saveBrowserPipelineBtn" class="btn btn-success" th:text="#{saveToBrowser}"></button>
<button id="savePipelineBtn" class="btn btn-success" th:text="#{pipelineOptions.saveButton}"></button> <button id="savePipelineBtn" class="btn btn-success" th:text="#{pipelineOptions.saveButton}"></button>
<button id="validateButton" class="btn btn-success" th:text="#{pipelineOptions.validateButton}"></button> <button id="validateButton" class="btn btn-success" th:text="#{pipelineOptions.validateButton}"></button>

126
test2.sh Normal file
View File

@@ -0,0 +1,126 @@
#!/bin/bash
# Default values
build_type="full"
enable_security="false"
run_compose="true"
# Function to parse command line arguments
parse_args() {
case "$1" in
""|-lite|-ultra-lite) build_type="$1";;
esac
case "$2" in
true|false) enable_security="$2";;
esac
case "$3" in
true|false) run_compose="$3";;
esac
}
# Function to check the health of the service with a timeout of 80 seconds
check_health() {
local service_name=$1
local compose_file=$2
local end=$((SECONDS+80)) # Fixed the timeout to be 80 seconds as per the function comment
echo -n "Waiting for $service_name to become healthy..."
until [ "$(docker inspect --format='{{json .State.Health.Status}}' "$service_name")" == '"healthy"' ] || [ $SECONDS -ge $end ]; do
sleep 3
echo -n "."
if [ $SECONDS -ge $end ]; then
echo -e "\n$service_name health check timed out after 80 seconds."
echo "Printing logs for $service_name:"
docker logs "$service_name"
return 1
fi
done
echo -e "\n$service_name is healthy!"
echo "Printing logs for $service_name:"
docker logs "$service_name"
return 0
}
# Function to build and test a Docker Compose configuration
# Function to build and test a Docker Compose configuration
# Function to build and test a Docker Compose configuration
build_and_test() {
local version_tag="alpha"
local dockerfile_name="./Dockerfile"
local image_base="frooodle/s-pdf"
local security_suffix=""
local docker_compose_base="./exampleYmlFiles/docker-compose-latest"
local compose_suffix=".yml"
local service_name_base="Stirling-PDF"
if [ "$enable_security" == "true" ]; then
security_suffix="-Security"
docker_compose_base+="-security" # Append to base name for Docker Compose files with security
fi
case "$build_type" in
full)
dockerfile_name="./Dockerfile"
;;
lite)
dockerfile_name="./Dockerfile-lite"
;;
ultra-lite)
dockerfile_name="./Dockerfile-ultra-lite"
;;
esac
# Dynamic image tag and service name based on build type and security
local image_tag="${image_base}:latest${build_type}${security_suffix}"
local service_name="${service_name_base}${build_type^}${security_suffix}"
local compose_file="${docker_compose_base}${build_type}${compose_suffix}"
# Gradle build with or without security
echo "Running ./gradlew clean build with security=$enable_security..."
./gradlew clean build
if [ $? -ne 0 ]; then
echo "Gradle build failed, exiting script."
exit 1
fi
# Building Docker image
echo "Building Docker image $image_tag with Dockerfile $dockerfile_name..."
docker build --build-arg VERSION_TAG=$version_tag -t $image_tag -f $dockerfile_name .
if [ "$run_compose" == "true" ]; then
echo "Running Docker Compose for $build_type with security=$enable_security..."
docker-compose -f "$compose_file" up -d
# Health check using the dynamic service name
if ! check_health "$service_name" "$compose_file"; then
echo "$service_name health check failed."
docker-compose -f "$compose_file" down
exit 1
else
# If the health check passes, prompt the user to press any key to tear down the service
read -n 1 -s -r -p "Health check passed. Press any key to tear down the service."
echo "" # Move to a new line
# Tear down the service
docker-compose -f "$compose_file" down
fi
# Tear down the service after the health check passes
#docker-compose -f "$compose_file" down
fi
}
# Main function
main() {
SECONDS=0
parse_args "$@"
build_and_test
echo "All operations completed in $SECONDS seconds."
}
main "$@"