Merge pull request #623 from Stirling-Tools/changes
pipeline Changes and example yml for testing
This commit is contained in:
commit
7389543af6
43 changed files with 3324 additions and 2118 deletions
14
build.gradle
14
build.gradle
|
@ -1,6 +1,6 @@
|
|||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '3.1.2'
|
||||
id 'org.springframework.boot' version '3.2.1'
|
||||
id 'io.spring.dependency-management' version '1.1.3'
|
||||
id 'org.springdoc.openapi-gradle-plugin' version '1.8.0'
|
||||
id "io.swagger.swaggerhub" version "1.3.2"
|
||||
|
@ -80,17 +80,19 @@ dependencies {
|
|||
//security updates
|
||||
implementation 'ch.qos.logback:logback-classic:1.4.14'
|
||||
implementation 'ch.qos.logback:logback-core:1.4.14'
|
||||
implementation 'org.springframework:spring-webmvc:6.0.15'
|
||||
implementation 'org.springframework:spring-webmvc:6.1.2'
|
||||
|
||||
implementation 'org.yaml:snakeyaml:2.1'
|
||||
implementation 'org.yaml:snakeyaml:2.2'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web:3.2.1'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.2.1'
|
||||
|
||||
if (System.getenv('DOCKER_ENABLE_SECURITY') != 'false') {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security:3.2.1'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE'
|
||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
|
||||
implementation "com.h2database:h2"
|
||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa:3.2.1"
|
||||
|
||||
//2.2.x requires rebuild of DB file.. need migration path
|
||||
implementation "com.h2database:h2:2.1.214"
|
||||
}
|
||||
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.2.1'
|
||||
|
@ -122,7 +124,7 @@ dependencies {
|
|||
//general PDF
|
||||
|
||||
// https://mvnrepository.com/artifact/com.opencsv/opencsv
|
||||
implementation ('com.opencsv:opencsv:5.7.1') {
|
||||
implementation ('com.opencsv:opencsv:5.9') {
|
||||
exclude group: 'commons-logging', module: 'commons-logging'
|
||||
}
|
||||
|
||||
|
|
31
exampleYmlFiles/docker-compose-latest-lite-security.yml
Normal file
31
exampleYmlFiles/docker-compose-latest-lite-security.yml
Normal file
|
@ -0,0 +1,31 @@
|
|||
version: '3.3'
|
||||
services:
|
||||
stirling-pdf:
|
||||
container_name: Stirling-PDF-Lite-Security
|
||||
image: frooodle/s-pdf:latest-lite
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 2G
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -q 'Please sign in'"]
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 16
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /stirling/latest/data:/usr/share/tesseract-ocr/5/tessdata:rw
|
||||
- /stirling/latest/config:/configs:rw
|
||||
- /stirling/latest/logs:/logs:rw
|
||||
environment:
|
||||
DOCKER_ENABLE_SECURITY: "true"
|
||||
SECURITY_ENABLELOGIN: "true"
|
||||
SYSTEM_DEFAULTLOCALE: en_US
|
||||
UI_APPNAME: Stirling-PDF-Lite
|
||||
UI_HOMEDESCRIPTION: Demo site for Stirling-PDF-Lite Latest with Security
|
||||
UI_APPNAMENAVBAR: Stirling-PDF-Lite Latest
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
restart: on-failure:5
|
30
exampleYmlFiles/docker-compose-latest-lite.yml
Normal file
30
exampleYmlFiles/docker-compose-latest-lite.yml
Normal file
|
@ -0,0 +1,30 @@
|
|||
version: '3.3'
|
||||
services:
|
||||
stirling-pdf:
|
||||
container_name: Stirling-PDF-Lite
|
||||
image: frooodle/s-pdf:latest-lite
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 2G
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -qv 'Please sign in'"]
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 16
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /stirling/latest/config:/configs:rw
|
||||
- /stirling/latest/logs:/logs:rw
|
||||
environment:
|
||||
DOCKER_ENABLE_SECURITY: "false"
|
||||
SECURITY_ENABLELOGIN: "false"
|
||||
SYSTEM_DEFAULTLOCALE: en_US
|
||||
UI_APPNAME: Stirling-PDF-Lite
|
||||
UI_HOMEDESCRIPTION: Demo site for Stirling-PDF-Lite Latest
|
||||
UI_APPNAMENAVBAR: Stirling-PDF-Lite Latest
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
restart: on-failure:5
|
31
exampleYmlFiles/docker-compose-latest-security.yml
Normal file
31
exampleYmlFiles/docker-compose-latest-security.yml
Normal file
|
@ -0,0 +1,31 @@
|
|||
version: '3.3'
|
||||
services:
|
||||
stirling-pdf:
|
||||
container_name: Stirling-PDF-Security
|
||||
image: frooodle/s-pdf:latest
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 4G
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -q 'Please sign in'"]
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 16
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /stirling/latest/data:/usr/share/tesseract-ocr/5/tessdata:rw
|
||||
- /stirling/latest/config:/configs:rw
|
||||
- /stirling/latest/logs:/logs:rw
|
||||
environment:
|
||||
DOCKER_ENABLE_SECURITY: "true"
|
||||
SECURITY_ENABLELOGIN: "true"
|
||||
SYSTEM_DEFAULTLOCALE: en_US
|
||||
UI_APPNAME: Stirling-PDF
|
||||
UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest with Security
|
||||
UI_APPNAMENAVBAR: Stirling-PDF Latest
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
restart: on-failure:5
|
|
@ -0,0 +1,31 @@
|
|||
version: '3.3'
|
||||
services:
|
||||
stirling-pdf:
|
||||
container_name: Stirling-PDF-Ultra-Lite-Security
|
||||
image: frooodle/s-pdf:latest-ultra-lite
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -q 'Please sign in'"]
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 16
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /stirling/latest/data:/usr/share/tesseract-ocr/5/tessdata:rw
|
||||
- /stirling/latest/config:/configs:rw
|
||||
- /stirling/latest/logs:/logs:rw
|
||||
environment:
|
||||
DOCKER_ENABLE_SECURITY: "true"
|
||||
SECURITY_ENABLELOGIN: "true"
|
||||
SYSTEM_DEFAULTLOCALE: en_US
|
||||
UI_APPNAME: Stirling-PDF-Lite
|
||||
UI_HOMEDESCRIPTION: Demo site for Stirling-PDF-Lite Latest with Security
|
||||
UI_APPNAMENAVBAR: Stirling-PDF-Lite Latest
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
restart: on-failure:5
|
30
exampleYmlFiles/docker-compose-latest-ultra-lite.yml
Normal file
30
exampleYmlFiles/docker-compose-latest-ultra-lite.yml
Normal file
|
@ -0,0 +1,30 @@
|
|||
version: '3.3'
|
||||
services:
|
||||
stirling-pdf:
|
||||
container_name: Stirling-PDF-Ultra-Lite
|
||||
image: frooodle/s-pdf:latest-ultra-lite
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -qv 'Please sign in'"]
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 16
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /stirling/latest/config:/configs:rw
|
||||
- /stirling/latest/logs:/logs:rw
|
||||
environment:
|
||||
DOCKER_ENABLE_SECURITY: "false"
|
||||
SECURITY_ENABLELOGIN: "false"
|
||||
SYSTEM_DEFAULTLOCALE: en_US
|
||||
UI_APPNAME: Stirling-PDF-Ultra-lite
|
||||
UI_HOMEDESCRIPTION: Demo site for Stirling-PDF-Ultra-lite Latest
|
||||
UI_APPNAMENAVBAR: Stirling-PDF-Ultra-lite Latest
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
restart: on-failure:5
|
31
exampleYmlFiles/docker-compose-latest.yml
Normal file
31
exampleYmlFiles/docker-compose-latest.yml
Normal file
|
@ -0,0 +1,31 @@
|
|||
version: '3.3'
|
||||
services:
|
||||
stirling-pdf:
|
||||
container_name: Stirling-PDF
|
||||
image: frooodle/s-pdf:latest
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 4G
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -qv 'Please sign in'"]
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 16
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /stirling/latest/data:/usr/share/tesseract-ocr/5/tessdata:rw
|
||||
- /stirling/latest/config:/configs:rw
|
||||
- /stirling/latest/logs:/logs:rw
|
||||
environment:
|
||||
DOCKER_ENABLE_SECURITY: "false"
|
||||
SECURITY_ENABLELOGIN: "false"
|
||||
SYSTEM_DEFAULTLOCALE: en_US
|
||||
UI_APPNAME: Stirling-PDF
|
||||
UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest
|
||||
UI_APPNAMENAVBAR: Stirling-PDF Latest
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "true"
|
||||
restart: on-failure:5
|
|
@ -102,7 +102,9 @@ public class SecurityConfiguration {
|
|||
|| trimmedUri.startsWith("/images/")
|
||||
|| trimmedUri.startsWith("/public/")
|
||||
|| trimmedUri.startsWith("/css/")
|
||||
|| trimmedUri.startsWith("/js/");
|
||||
|| trimmedUri.startsWith("/js/")
|
||||
|| trimmedUri.startsWith(
|
||||
"/api/v1/info/status");
|
||||
})
|
||||
.permitAll()
|
||||
.anyRequest()
|
||||
|
@ -113,6 +115,7 @@ public class SecurityConfiguration {
|
|||
http.csrf(csrf -> csrf.disable())
|
||||
.authorizeHttpRequests(authz -> authz.anyRequest().permitAll());
|
||||
}
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
|
|||
contextPath + "/css/",
|
||||
contextPath + "/js/",
|
||||
contextPath + "/pdfjs/",
|
||||
contextPath + "/api/v1/info/status",
|
||||
contextPath + "/site.webmanifest"
|
||||
};
|
||||
|
||||
|
|
|
@ -119,7 +119,11 @@ public class SplitPdfBySectionsController {
|
|||
// Set clipping area and position
|
||||
float translateX = -subPageWidth * i;
|
||||
float translateY = height - subPageHeight * (verticalDivisions - j);
|
||||
|
||||
|
||||
|
||||
//Code for google Docs pdfs..
|
||||
//float translateY = -subPageHeight * (verticalDivisions - 1 - j);
|
||||
|
||||
contentStream.saveGraphicsState();
|
||||
contentStream.addRect(0, 0, subPageWidth, subPageHeight);
|
||||
contentStream.clip();
|
||||
|
|
|
@ -79,7 +79,7 @@ public class ConvertOfficeController {
|
|||
@Operation(
|
||||
summary = "Convert a file to a PDF using LibreOffice",
|
||||
description =
|
||||
"This endpoint converts a given file to a PDF using LibreOffice API Input:Any Output:PDF Type:SISO")
|
||||
"This endpoint converts a given file to a PDF using LibreOffice API Input:ANY Output:PDF Type:SISO")
|
||||
public ResponseEntity<byte[]> processFileToPDF(@ModelAttribute GeneralFile request)
|
||||
throws Exception {
|
||||
MultipartFile inputFile = request.getFileInput();
|
||||
|
|
|
@ -2,7 +2,9 @@ package stirling.software.SPDF.controller.api.pipeline;
|
|||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
|
@ -84,9 +86,26 @@ public class PipelineController {
|
|||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ZipOutputStream zipOut = new ZipOutputStream(baos);
|
||||
|
||||
// A map to keep track of filenames and their counts
|
||||
Map<String, Integer> filenameCount = new HashMap<>();
|
||||
|
||||
// Loop through each file and add it to the zip
|
||||
for (Resource file : outputFiles) {
|
||||
ZipEntry zipEntry = new ZipEntry(file.getFilename());
|
||||
String originalFilename = file.getFilename();
|
||||
String filename = originalFilename;
|
||||
|
||||
// Check if the filename already exists, and modify it if necessary
|
||||
if (filenameCount.containsKey(originalFilename)) {
|
||||
int count = filenameCount.get(originalFilename);
|
||||
String baseName = originalFilename.replaceAll("\\.[^.]*$", "");
|
||||
String extension = originalFilename.replaceAll("^.*\\.", "");
|
||||
filename = baseName + "(" + count + ")." + extension;
|
||||
filenameCount.put(originalFilename, count + 1);
|
||||
} else {
|
||||
filenameCount.put(originalFilename, 1);
|
||||
}
|
||||
|
||||
ZipEntry zipEntry = new ZipEntry(filename);
|
||||
zipOut.putNextEntry(zipEntry);
|
||||
|
||||
// Read the file into a byte array
|
||||
|
|
|
@ -5,6 +5,8 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
@ -132,8 +134,6 @@ public class PipelineProcessor {
|
|||
+ operation);
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
outputFiles = newOutputFiles;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -185,10 +185,12 @@ public class PipelineProcessor {
|
|||
}
|
||||
}
|
||||
logPrintStream.close();
|
||||
outputFiles = newOutputFiles;
|
||||
}
|
||||
if (hasErrors) {
|
||||
logger.error("Errors occurred during processing. Log: {}", logStream.toString());
|
||||
}
|
||||
|
||||
return outputFiles;
|
||||
}
|
||||
|
||||
|
@ -196,6 +198,7 @@ public class PipelineProcessor {
|
|||
RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
// Set up headers, including API key
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
String apiKey = getApiKeyForUser();
|
||||
headers.add("X-API-Key", apiKey);
|
||||
|
@ -216,11 +219,12 @@ public class PipelineProcessor {
|
|||
throws IOException {
|
||||
// Define filename
|
||||
String newFilename;
|
||||
if ("auto-rename".equals(operation)) {
|
||||
if (operation.contains("auto-rename")) {
|
||||
// If the operation is "auto-rename", generate a new filename.
|
||||
// This is a simple example of generating a filename using current timestamp.
|
||||
// Modify as per your needs.
|
||||
newFilename = "file_" + System.currentTimeMillis();
|
||||
|
||||
newFilename = extractFilename(response);
|
||||
} else {
|
||||
// Otherwise, keep the original filename.
|
||||
newFilename = fileName;
|
||||
|
@ -244,6 +248,28 @@ public class PipelineProcessor {
|
|||
return newOutputFiles;
|
||||
}
|
||||
|
||||
public String extractFilename(ResponseEntity<byte[]> response) {
|
||||
String filename = "default-filename.ext"; // Default filename if not found
|
||||
|
||||
HttpHeaders headers = response.getHeaders();
|
||||
String contentDisposition = headers.getFirst(HttpHeaders.CONTENT_DISPOSITION);
|
||||
|
||||
if (contentDisposition != null && !contentDisposition.isEmpty()) {
|
||||
String[] parts = contentDisposition.split(";");
|
||||
for (String part : parts) {
|
||||
if (part.trim().startsWith("filename")) {
|
||||
// Extracts filename and removes quotes if present
|
||||
filename = part.split("=")[1].trim().replace("\"", "");
|
||||
filename = URLDecoder.decode(filename, StandardCharsets.UTF_8);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
List<Resource> generateInputFiles(File[] files) throws Exception {
|
||||
if (files == null || files.length == 0) {
|
||||
logger.info("No files");
|
||||
|
|
|
@ -59,6 +59,14 @@ public class GeneralWebController {
|
|||
.readValue(config, new TypeReference<Map<String, Object>>() {});
|
||||
|
||||
String name = (String) jsonContent.get("name");
|
||||
if (name == null || name.length() < 1) {
|
||||
String filename =
|
||||
jsonFiles
|
||||
.get(pipelineConfigs.indexOf(config))
|
||||
.getFileName()
|
||||
.toString();
|
||||
name = filename.substring(0, filename.lastIndexOf('.'));
|
||||
}
|
||||
Map<String, String> configWithName = new HashMap<>();
|
||||
configWithName.put("json", config);
|
||||
configWithName.put("name", name);
|
||||
|
|
|
@ -9,6 +9,7 @@ public class RequestUriUtils {
|
|||
|| requestURI.startsWith("/images/")
|
||||
|| requestURI.startsWith("/public/")
|
||||
|| requestURI.startsWith("/pdfjs/")
|
||||
|| requestURI.endsWith(".svg");
|
||||
|| requestURI.endsWith(".svg")
|
||||
|| requestURI.startsWith("/api/v1/info/status");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
fileToPDF.fileTypesList=Microsoft Word: (DOC, DOCX, DOT, DOTX) <br> \
|
||||
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> \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Red
|
|||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Credentials changed!
|
||||
notAuthenticatedMessage=User not authenticated.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Current password is incorrect.
|
|||
usernameExistsMessage=New Username already exists.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Червено
|
|||
green=Зелено
|
||||
blue=Синьо
|
||||
custom=Персонализиране...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Идентификационните данни са променени!
|
||||
notAuthenticatedMessage=Потребителят не е автентикиран.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Текущата парола е неправилна.
|
|||
usernameExistsMessage=Новият потребител вече съществува.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Vermell
|
|||
green=Verd
|
||||
blue=Blau
|
||||
custom=Personalitzat...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Credentials changed!
|
||||
notAuthenticatedMessage=User not authenticated.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Current password is incorrect.
|
|||
usernameExistsMessage=New Username already exists.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Rot
|
|||
green=Grün
|
||||
blue=Blau
|
||||
custom=benutzerdefiniert...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Anmeldedaten geändert!
|
||||
notAuthenticatedMessage=Benutzer nicht authentifiziert.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Das Passwort ist falsch.
|
|||
usernameExistsMessage=Neuer Benutzername existiert bereits.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=\u039A\u03CC\u03BA\u03BA\u03B9\u03BD\u03BF
|
|||
green=\u03A0\u03C1\u03AC\u03C3\u03B9\u03BD\u03BF
|
||||
blue=\u039C\u03C0\u03BB\u03AD
|
||||
custom=\u03A0\u03C1\u03BF\u03C3\u03B1\u03C1\u03BC\u03BF\u03B3\u03AE...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=\u03A4\u03B1 \u03B4\u03B9\u03B1\u03C0\u03B9\u03C3\u03C4\u03B5\u03C5\u03C4\u03AE\u03C1\u03B9\u03B1 \u03AD\u03C7\u03BF\u03C5\u03BD \u03B1\u03BB\u03BB\u03AC\u03BE\u03B5\u03B9!
|
||||
notAuthenticatedMessage=\u039F \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7\u03C2 \u03B4\u03B5\u03BD \u03AD\u03C7\u03B5\u03B9 \u03B1\u03C5\u03B8\u03B5\u03BD\u03C4\u03B9\u03BA\u03BF\u03C0\u03BF\u03B9\u03B7\u03B8\u03B5\u03AF.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=\u039F \u03C4\u03C1\u03AD\u03C7\u03C9\u03BD \u03BA\u03C
|
|||
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.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Red
|
|||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Credentials changed!
|
||||
notAuthenticatedMessage=User not authenticated.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Current password is incorrect.
|
|||
usernameExistsMessage=New Username already exists.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Red
|
|||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Credentials changed!
|
||||
notAuthenticatedMessage=User not authenticated.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Current password is incorrect.
|
|||
usernameExistsMessage=New Username already exists.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Rojo
|
|||
green=Verde
|
||||
blue=Azul
|
||||
custom=Personalizado...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Se cambiaron las credenciales!
|
||||
notAuthenticatedMessage=Usuario no autentificado.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=La contraseña actual no es correcta.
|
|||
usernameExistsMessage=El nuevo nombre de usuario está en uso.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Gorria
|
|||
green=Berdea
|
||||
blue=Urdina
|
||||
custom=Pertsonalizatu...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Credentials changed!
|
||||
notAuthenticatedMessage=User not authenticated.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Current password is incorrect.
|
|||
usernameExistsMessage=New Username already exists.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Rouge
|
|||
green=Vert
|
||||
blue=Bleu
|
||||
custom=Personnalisé\u2026
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Les identifiants ont été mis à jour\u00a0!
|
||||
notAuthenticatedMessage=Utilisateur non authentifié.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Le mot de passe actuel est incorrect.
|
|||
usernameExistsMessage=Le nouveau nom d\u2019utilisateur existe déjà.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=लाल
|
|||
green=हरा
|
||||
blue=नीला
|
||||
custom=कस्टम...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=क्रेडेंशियल्स बदल दी गईं!
|
||||
notAuthenticatedMessage=उपयोगकर्ता प्रमाणित नहीं है।
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=वर्तमान पासवर्ड गलत
|
|||
usernameExistsMessage=नया उपयोगकर्ता नाम पहले से मौजूद है।
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Piros
|
|||
green=Zöld
|
||||
blue=Kék
|
||||
custom=Egyedi...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=A hitelek megváltoztak!
|
||||
notAuthenticatedMessage=Felhasználó nincs hitelesítve.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=A jelenlegi jelszó helytelen.
|
|||
usernameExistsMessage=Az új felhasználónév már létezik.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl=right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Merah
|
|||
green=Hijau
|
||||
blue=Biru
|
||||
custom=Kustom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Kredensial berubah!!
|
||||
notAuthenticatedMessage=Pengguna tidak ter-autentikasi.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Kata sandi saat ini salah.
|
|||
usernameExistsMessage=Nama pengguna baru sudah ada.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Rosso
|
|||
green=Verde
|
||||
blue=Blu
|
||||
custom=Personalizzato
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Credenziali cambiate!
|
||||
notAuthenticatedMessage=Utente non autenticato.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=La password attuale non è corretta.
|
|||
usernameExistsMessage=Il nuovo nome utente esiste già.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=赤
|
|||
green=緑
|
||||
blue=青
|
||||
custom=カスタム...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=資格情報が変更されました!
|
||||
notAuthenticatedMessage=ユーザーが認証されていません。
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=現在のパスワードが正しくありません。
|
|||
usernameExistsMessage=新しいユーザー名はすでに存在します。
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Red
|
|||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=계정 정보 변경 성공!
|
||||
notAuthenticatedMessage=User not authenticated.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=현재 비밀번호가 틀립니다.
|
|||
usernameExistsMessage=새 사용자명이 이미 존재합니다.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Red
|
|||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Credentials changed!
|
||||
notAuthenticatedMessage=User not authenticated.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Current password is incorrect.
|
|||
usernameExistsMessage=New Username already exists.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Red
|
|||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Credentials changed!
|
||||
notAuthenticatedMessage=User not authenticated.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Current password is incorrect.
|
|||
usernameExistsMessage=New Username already exists.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Red
|
|||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Credentials changed!
|
||||
notAuthenticatedMessage=User not authenticated.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Current password is incorrect.
|
|||
usernameExistsMessage=New Username already exists.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Red
|
|||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Credentials changed!
|
||||
notAuthenticatedMessage=User not authenticated.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Current password is incorrect.
|
|||
usernameExistsMessage=New Username already exists.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Kırmızı
|
|||
green=Yeşil
|
||||
blue=Mavi
|
||||
custom=Özel
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=Bilgiler değiştirildi!
|
||||
notAuthenticatedMessage=Kullanıcı doğrulanmadı.
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=Mevcut şifre yanlış.
|
|||
usernameExistsMessage=Yeni Kullanıcı Adı zaten var.
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
|
@ -42,6 +42,7 @@ red=Red
|
|||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
|
||||
changedCredsMessage=凭证已更改!
|
||||
notAuthenticatedMessage=用户未经过身份验证。
|
||||
|
@ -50,6 +51,29 @@ incorrectPasswordMessage=当前密码不正确。
|
|||
usernameExistsMessage=新用户名已存在。
|
||||
|
||||
|
||||
###############
|
||||
# Pipeline #
|
||||
###############
|
||||
pipeline.header=Pipeline Menu (Alpha)
|
||||
pipeline.uploadButton=Upload Custom
|
||||
pipeline.configureButton=Configure
|
||||
pipeline.defaultOption=Custom
|
||||
pipeline.submitButton=Submit
|
||||
|
||||
######################
|
||||
# Pipeline Options #
|
||||
######################
|
||||
pipelineOptions.header=Pipeline Configuration
|
||||
pipelineOptions.pipelineNameLabel=Pipeline Name
|
||||
pipelineOptions.saveSettings=Save Settings
|
||||
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
|
||||
pipelineOptions.addOperationButton=Add operation
|
||||
pipelineOptions.pipelineHeader=Pipeline:
|
||||
pipelineOptions.saveButton=Download
|
||||
pipelineOptions.validateButton=Validate
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# NAVBAR #
|
||||
|
|
|
@ -19,7 +19,7 @@ function validatePipeline() {
|
|||
// Strip off 'ZIP-' prefix
|
||||
currentOperationDescription = currentOperationDescription.replace("ZIP-", '');
|
||||
nextOperationDescription = nextOperationDescription.replace("ZIP-", '');
|
||||
|
||||
|
||||
let currentOperationOutput = currentOperationDescription.match(/Output:([A-Z\/]*)/)?.[1] || "";
|
||||
let nextOperationInput = nextOperationDescription.match(/Input:([A-Z\/]*)/)?.[1] || "";
|
||||
|
||||
|
@ -57,14 +57,14 @@ function validatePipeline() {
|
|||
}
|
||||
|
||||
function updateValidateButton(isValid) {
|
||||
var validateButton = document.getElementById('validateButton');
|
||||
if (isValid) {
|
||||
validateButton.classList.remove('btn-danger');
|
||||
validateButton.classList.add('btn-success');
|
||||
} else {
|
||||
validateButton.classList.remove('btn-success');
|
||||
validateButton.classList.add('btn-danger');
|
||||
}
|
||||
var validateButton = document.getElementById('validateButton');
|
||||
if (isValid) {
|
||||
validateButton.classList.remove('btn-danger');
|
||||
validateButton.classList.add('btn-success');
|
||||
} else {
|
||||
validateButton.classList.remove('btn-success');
|
||||
validateButton.classList.add('btn-danger');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,7 +77,7 @@ document.getElementById('submitConfigBtn').addEventListener('click', function()
|
|||
}
|
||||
let selectedOperation = document.getElementById('operationsDropdown').value;
|
||||
|
||||
|
||||
|
||||
|
||||
var pipelineName = document.getElementById('pipelineName').value;
|
||||
let pipelineList = document.getElementById('pipelineList').children;
|
||||
|
@ -101,18 +101,18 @@ document.getElementById('submitConfigBtn').addEventListener('click', function()
|
|||
"parameters": parameters
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
let pipelineConfigJson = JSON.stringify(pipelineConfig, null, 2);
|
||||
|
||||
|
@ -131,34 +131,34 @@ document.getElementById('submitConfigBtn').addEventListener('click', function()
|
|||
console.log("formData", formData);
|
||||
|
||||
fetch('api/v1/pipeline/handleData', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => {
|
||||
// Save the response to use it later
|
||||
const responseToUseLater = response;
|
||||
|
||||
return response.blob().then(blob => {
|
||||
let url = window.URL.createObjectURL(blob);
|
||||
let a = document.createElement('a');
|
||||
a.href = url;
|
||||
|
||||
// Use responseToUseLater instead of response
|
||||
const contentDisposition = responseToUseLater.headers.get('Content-Disposition');
|
||||
let filename = 'download';
|
||||
if (contentDisposition && contentDisposition.indexOf('attachment') !== -1) {
|
||||
filename = decodeURIComponent(contentDisposition.split('filename=')[1].replace(/"/g, '')).trim();
|
||||
}
|
||||
a.download = filename;
|
||||
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
.then(response => {
|
||||
// Save the response to use it later
|
||||
const responseToUseLater = response;
|
||||
|
||||
return response.blob().then(blob => {
|
||||
let url = window.URL.createObjectURL(blob);
|
||||
let a = document.createElement('a');
|
||||
a.href = url;
|
||||
|
||||
// Use responseToUseLater instead of response
|
||||
const contentDisposition = responseToUseLater.headers.get('Content-Disposition');
|
||||
let filename = 'download';
|
||||
if (contentDisposition && contentDisposition.indexOf('attachment') !== -1) {
|
||||
filename = decodeURIComponent(contentDisposition.split('filename=')[1].replace(/"/g, '')).trim();
|
||||
}
|
||||
a.download = filename;
|
||||
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
@ -182,10 +182,11 @@ fetch('v1/api-docs')
|
|||
// Group operations by tags
|
||||
Object.keys(data.paths).forEach(operationPath => {
|
||||
let operation = data.paths[operationPath].post;
|
||||
if(!operation || !operation.description) {
|
||||
if (!operation || !operation.description) {
|
||||
console.log(operationPath);
|
||||
}
|
||||
if (operation && !ignoreOperations.includes(operationPath) && !operation.description.includes("Type:MISO")) {
|
||||
//!operation.description.includes("Type:MISO")
|
||||
if (operation && !ignoreOperations.includes(operationPath)) {
|
||||
let operationTag = operation.tags[0]; // This assumes each operation has exactly one tag
|
||||
if (!operationsByTag[operationTag]) {
|
||||
operationsByTag[operationTag] = [];
|
||||
|
@ -193,6 +194,12 @@ fetch('v1/api-docs')
|
|||
operationsByTag[operationTag].push(operationPath);
|
||||
}
|
||||
});
|
||||
|
||||
// Sort operations within each tag alphabetically
|
||||
Object.keys(operationsByTag).forEach(tag => {
|
||||
operationsByTag[tag].sort();
|
||||
});
|
||||
|
||||
// Specify the order of tags
|
||||
let tagOrder = ["General", "Security", "Convert", "Misc", "Filter"];
|
||||
|
||||
|
@ -204,17 +211,17 @@ fetch('v1/api-docs')
|
|||
|
||||
operationsByTag[tag].forEach(operationPath => {
|
||||
let option = document.createElement('option');
|
||||
|
||||
|
||||
let operationPathDisplay = operationPath
|
||||
operationPathDisplay = operationPath.replace(new RegExp("api/v1/" + tag.toLowerCase() + "/", 'i'), "");
|
||||
|
||||
|
||||
if(operationPath.includes("/convert")){
|
||||
|
||||
|
||||
if (operationPath.includes("/convert")) {
|
||||
operationPathDisplay = operationPathDisplay.replace(/^\//, '').replaceAll("/", " to ");
|
||||
} else {
|
||||
operationPathDisplay = operationPathDisplay.replace(/\//g, ''); // Remove slashes
|
||||
}
|
||||
operationPathDisplay = operationPathDisplay.replaceAll(" ","-");
|
||||
operationPathDisplay = operationPathDisplay.replaceAll(" ", "-");
|
||||
option.textContent = operationPathDisplay;
|
||||
option.value = operationPath; // Keep the value with slashes for querying
|
||||
group.appendChild(option);
|
||||
|
@ -234,37 +241,43 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
listItem.className = "list-group-item";
|
||||
let hasSettings = false;
|
||||
if (apiDocs[selectedOperation] && apiDocs[selectedOperation].post) {
|
||||
const postMethod = apiDocs[selectedOperation].post;
|
||||
|
||||
// Check if parameters exist
|
||||
if (postMethod.parameters && postMethod.parameters.length > 0) {
|
||||
hasSettings = true;
|
||||
} else if (postMethod.requestBody && postMethod.requestBody.content['multipart/form-data']) {
|
||||
// Extract the reference key
|
||||
const refKey = postMethod.requestBody.content['multipart/form-data'].schema['$ref'].split('/').pop();
|
||||
// Check if the referenced schema exists and has properties
|
||||
if (apiSchemas[refKey] && Object.keys(apiSchemas[refKey].properties).length > 0) {
|
||||
hasSettings = true;
|
||||
}
|
||||
}
|
||||
const postMethod = apiDocs[selectedOperation].post;
|
||||
|
||||
// Check if parameters exist
|
||||
if (postMethod.parameters && postMethod.parameters.length > 0) {
|
||||
hasSettings = true;
|
||||
} else if (postMethod.requestBody && postMethod.requestBody.content['multipart/form-data']) {
|
||||
// Extract the reference key
|
||||
const refKey = postMethod.requestBody.content['multipart/form-data'].schema['$ref'].split('/').pop();
|
||||
// Check if the referenced schema exists and has properties more than just its input file
|
||||
if (apiSchemas[refKey]) {
|
||||
const properties = apiSchemas[refKey].properties;
|
||||
const propertyKeys = Object.keys(properties);
|
||||
|
||||
// Check if there's more than one property or if there's exactly one property and its format is not 'binary'
|
||||
if (propertyKeys.length > 1 || (propertyKeys.length === 1 && properties[propertyKeys[0]].format !== 'binary')) {
|
||||
hasSettings = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
listItem.innerHTML = `
|
||||
<div class="d-flex justify-content-between align-items-center w-100">
|
||||
<div class="operationName">${selectedOperation}</div>
|
||||
<div class="arrows d-flex">
|
||||
<button class="btn btn-secondary move-up ms-1"><span>↑</span></button>
|
||||
<button class="btn btn-secondary move-down ms-1"><span>↓</span></button>
|
||||
<button class="btn ${hasSettings ? 'btn-warning' : 'btn-secondary'} pipelineSettings ms-1" ${hasSettings ? "" : "disabled"}>
|
||||
<span style="color: ${hasSettings ? "white" : "grey"};">⚙️</span>
|
||||
</button>
|
||||
<button class="btn btn-danger remove ms-1"><span>X</span></button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
<div class="d-flex justify-content-between align-items-center w-100">
|
||||
<div class="operationName">${selectedOperation}</div>
|
||||
<div class="arrows d-flex">
|
||||
<button class="btn btn-secondary move-up ms-1"><span>↑</span></button>
|
||||
<button class="btn btn-secondary move-down ms-1"><span>↓</span></button>
|
||||
<button class="btn ${hasSettings ? 'btn-warning' : 'btn-secondary'} pipelineSettings ms-1" ${hasSettings ? "" : "disabled"}>
|
||||
<span style="color: ${hasSettings ? "white" : "grey"};">⚙️</span>
|
||||
</button>
|
||||
<button class="btn btn-danger remove ms-1"><span>X</span></button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
pipelineList.appendChild(listItem);
|
||||
|
@ -273,6 +286,7 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
event.preventDefault();
|
||||
if (listItem.previousElementSibling) {
|
||||
pipelineList.insertBefore(listItem, listItem.previousElementSibling);
|
||||
updateConfigInDropdown();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -280,13 +294,16 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
event.preventDefault();
|
||||
if (listItem.nextElementSibling) {
|
||||
pipelineList.insertBefore(listItem.nextElementSibling, listItem);
|
||||
updateConfigInDropdown();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
listItem.querySelector('.remove').addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
pipelineList.removeChild(listItem);
|
||||
hideOrShowPipelineHeader();
|
||||
updateConfigInDropdown();
|
||||
});
|
||||
|
||||
listItem.querySelector('.pipelineSettings').addEventListener('click', function(event) {
|
||||
|
@ -303,19 +320,19 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
// Resolve the $ref reference to get actual schema properties
|
||||
let refKey = apiDocs[operation].post.requestBody.content['multipart/form-data'].schema['$ref'].split('/').pop();
|
||||
let requestBodyData = apiSchemas[refKey].properties || {};
|
||||
|
||||
|
||||
// Combine operationData and requestBodyData into a single array
|
||||
operationData = operationData.concat(Object.keys(requestBodyData).map(key => ({
|
||||
name: key,
|
||||
schema: requestBodyData[key]
|
||||
name: key,
|
||||
schema: requestBodyData[key]
|
||||
})));
|
||||
|
||||
pipelineSettingsContent.innerHTML = '';
|
||||
|
||||
operationData.forEach(parameter => {
|
||||
// If the parameter name is 'fileInput', return early to skip the rest of this iteration
|
||||
if (parameter.name === 'fileInput') return;
|
||||
|
||||
if (parameter.name === 'fileInput') return;
|
||||
|
||||
let parameterDiv = document.createElement('div');
|
||||
parameterDiv.className = "mb-3";
|
||||
|
||||
|
@ -324,12 +341,12 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
parameterLabel.title = parameter.schema.description;
|
||||
parameterLabel.setAttribute('for', parameter.name);
|
||||
parameterDiv.appendChild(parameterLabel);
|
||||
|
||||
let defaultValue = parameter.schema.example;
|
||||
if (defaultValue === undefined) defaultValue = parameter.schema.default;
|
||||
|
||||
let defaultValue = parameter.schema.example;
|
||||
if (defaultValue === undefined) defaultValue = parameter.schema.default;
|
||||
|
||||
let parameterInput;
|
||||
|
||||
|
||||
// check if enum exists in schema
|
||||
if (parameter.schema.enum) {
|
||||
// if enum exists, create a select element
|
||||
|
@ -349,15 +366,15 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
case 'string':
|
||||
if (parameter.schema.format === 'binary') {
|
||||
// This is a file input
|
||||
|
||||
|
||||
//parameterInput = document.createElement('input');
|
||||
//parameterInput.type = 'file';
|
||||
//parameterInput.className = "form-control";
|
||||
|
||||
|
||||
parameterInput = document.createElement('input');
|
||||
parameterInput.type = 'text';
|
||||
parameterInput.className = "form-control";
|
||||
parameterInput.value = "FileInputPathToBeInputtedManuallyOffline";
|
||||
parameterInput.value = "FileInputPathToBeInputtedManuallyForOffline";
|
||||
} else {
|
||||
parameterInput = document.createElement('input');
|
||||
parameterInput.type = 'text';
|
||||
|
@ -379,8 +396,9 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
break;
|
||||
case 'array':
|
||||
case 'object':
|
||||
//TODO compare to doc and check if fileInput array? parameter.schema.format === 'binary'
|
||||
parameterInput = document.createElement('textarea');
|
||||
parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}`;
|
||||
parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}, If this is a fileInput, it is not currently supported`;
|
||||
parameterInput.className = "form-control";
|
||||
break;
|
||||
default:
|
||||
|
@ -418,42 +436,48 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
|
||||
pipelineSettingsContent.appendChild(parameterDiv);
|
||||
});
|
||||
|
||||
let saveButton = document.createElement('button');
|
||||
saveButton.textContent = "Save Settings";
|
||||
saveButton.className = "btn btn-primary";
|
||||
saveButton.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
let settings = {};
|
||||
operationData.forEach(parameter => {
|
||||
if(parameter.name !== "fileInput"){
|
||||
let value = document.getElementById(parameter.name).value;
|
||||
switch (parameter.schema.type) {
|
||||
case 'number':
|
||||
case 'integer':
|
||||
settings[parameter.name] = Number(value);
|
||||
break;
|
||||
case 'boolean':
|
||||
settings[parameter.name] = document.getElementById(parameter.name).checked;
|
||||
break;
|
||||
case 'array':
|
||||
case 'object':
|
||||
try {
|
||||
settings[parameter.name] = JSON.parse(value);
|
||||
} catch (err) {
|
||||
console.error(`Invalid JSON format for ${parameter.name}`);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
settings[parameter.name] = value;
|
||||
|
||||
if(hasSettings) {
|
||||
let saveButton = document.createElement('button');
|
||||
saveButton.textContent = saveSettings;
|
||||
saveButton.className = "btn btn-primary";
|
||||
saveButton.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
let settings = {};
|
||||
operationData.forEach(parameter => {
|
||||
if (parameter.name !== "fileInput") {
|
||||
let value = document.getElementById(parameter.name).value;
|
||||
switch (parameter.schema.type) {
|
||||
case 'number':
|
||||
case 'integer':
|
||||
settings[parameter.name] = Number(value);
|
||||
break;
|
||||
case 'boolean':
|
||||
settings[parameter.name] = document.getElementById(parameter.name).checked;
|
||||
break;
|
||||
case 'array':
|
||||
case 'object':
|
||||
if (value === null || value === '') {
|
||||
settings[parameter.name] = '';
|
||||
} else {
|
||||
try {
|
||||
settings[parameter.name] = JSON.parse(value);
|
||||
} catch (err) {
|
||||
console.error(`Invalid JSON format for ${parameter.name}`);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
settings[parameter.name] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
operationSettings[operation] = settings;
|
||||
//pipelineSettingsModal.style.display = "none";
|
||||
});
|
||||
operationSettings[operation] = settings;
|
||||
//pipelineSettingsModal.style.display = "none";
|
||||
});
|
||||
pipelineSettingsContent.appendChild(saveButton);
|
||||
|
||||
pipelineSettingsContent.appendChild(saveButton);
|
||||
saveButton.click();
|
||||
}
|
||||
//pipelineSettingsModal.style.display = "block";
|
||||
|
||||
//pipelineSettingsModal.getElementsByClassName("close")[0].onclick = function() {
|
||||
|
@ -466,144 +490,182 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
|
|||
// }
|
||||
//}
|
||||
}
|
||||
showpipelineSettingsModal(selectedOperation);
|
||||
updateConfigInDropdown();
|
||||
hideOrShowPipelineHeader();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
function updateConfigInDropdown() {
|
||||
let pipelineSelect = document.getElementById('pipelineSelect');
|
||||
let selectedOption = pipelineSelect.options[pipelineSelect.selectedIndex];
|
||||
|
||||
// Get the current configuration as JSON
|
||||
let pipelineConfigJson = configToJson();
|
||||
console.log("pipelineConfigJson", pipelineConfigJson);
|
||||
if (!pipelineConfigJson) {
|
||||
console.error("Failed to update configuration: Invalid configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the value of the selected option with the new configuration
|
||||
selectedOption.value = pipelineConfigJson;
|
||||
|
||||
}
|
||||
|
||||
var saveBtn = document.getElementById('savePipelineBtn');
|
||||
|
||||
// Remove any existing event listeners
|
||||
saveBtn.removeEventListener('click', savePipeline);
|
||||
|
||||
// Add the event listener
|
||||
saveBtn.addEventListener('click', savePipeline);
|
||||
console.log("saveBtn", saveBtn)
|
||||
|
||||
function configToJson() {
|
||||
if (!validatePipeline()) {
|
||||
return null; // Return null if validation fails
|
||||
}
|
||||
|
||||
var pipelineName = document.getElementById('pipelineName').value;
|
||||
let pipelineList = document.getElementById('pipelineList').children;
|
||||
let pipelineConfig = {
|
||||
"name": pipelineName,
|
||||
"pipeline": [],
|
||||
"_examples": {
|
||||
"outputDir": "{outputFolder}/{folderName}",
|
||||
"outputFileName": "{filename}-{pipelineName}-{date}-{time}"
|
||||
},
|
||||
"outputDir": "{outputFolder}",
|
||||
"outputFileName": "{filename}"
|
||||
};
|
||||
|
||||
for (let i = 0; i < pipelineList.length; i++) {
|
||||
let operationName = pipelineList[i].querySelector('.operationName').textContent;
|
||||
let parameters = operationSettings[operationName] || {};
|
||||
|
||||
parameters['fileInput'] = 'automated';
|
||||
|
||||
pipelineConfig.pipeline.push({
|
||||
"operation": operationName,
|
||||
"parameters": parameters
|
||||
});
|
||||
}
|
||||
|
||||
return JSON.stringify(pipelineConfig, null, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function savePipeline() {
|
||||
let pipelineConfigJson = configToJson();
|
||||
if (!pipelineConfigJson) {
|
||||
console.error("Failed to save pipeline: Invalid configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
let pipelineName = document.getElementById('pipelineName').value;
|
||||
console.log("Downloading...");
|
||||
let a = document.createElement('a');
|
||||
a.href = URL.createObjectURL(new Blob([pipelineConfigJson], { type: 'application/json' }));
|
||||
a.download = pipelineName + '.json';
|
||||
a.style.display = 'none';
|
||||
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
|
||||
|
||||
async function processPipelineConfig(configString) {
|
||||
console.log("configString", configString);
|
||||
let pipelineConfig = JSON.parse(configString);
|
||||
let pipelineList = document.getElementById('pipelineList');
|
||||
|
||||
while (pipelineList.firstChild) {
|
||||
pipelineList.removeChild(pipelineList.firstChild);
|
||||
}
|
||||
document.getElementById('pipelineName').value = pipelineConfig.name
|
||||
for (const operationConfig of pipelineConfig.pipeline) {
|
||||
let operationsDropdown = document.getElementById('operationsDropdown');
|
||||
operationsDropdown.value = operationConfig.operation;
|
||||
operationSettings[operationConfig.operation] = operationConfig.parameters;
|
||||
|
||||
// assuming addOperation is async
|
||||
await new Promise((resolve) => {
|
||||
document.getElementById('addOperationBtn').addEventListener('click', resolve, { once: true });
|
||||
document.getElementById('addOperationBtn').click();
|
||||
});
|
||||
|
||||
let lastOperation = pipelineList.lastChild;
|
||||
|
||||
Object.keys(operationConfig.parameters).forEach(parameterName => {
|
||||
let input = document.getElementById(parameterName);
|
||||
if (input) {
|
||||
switch (input.type) {
|
||||
case 'checkbox':
|
||||
input.checked = operationConfig.parameters[parameterName];
|
||||
break;
|
||||
case 'number':
|
||||
input.value = operationConfig.parameters[parameterName].toString();
|
||||
break;
|
||||
case 'file':
|
||||
if (parameterName !== 'fileInput') {
|
||||
// Create a new file input element
|
||||
let newInput = document.createElement('input');
|
||||
newInput.type = 'file';
|
||||
newInput.id = parameterName;
|
||||
|
||||
// Add the new file input to the main page (change the selector according to your needs)
|
||||
document.querySelector('#main').appendChild(newInput);
|
||||
}
|
||||
break;
|
||||
case 'text':
|
||||
case 'textarea':
|
||||
default:
|
||||
input.value = JSON.stringify(operationConfig.parameters[parameterName]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('uploadPipelineBtn').addEventListener('click', function() {
|
||||
document.getElementById('uploadPipelineInput').click();
|
||||
});
|
||||
|
||||
document.getElementById('uploadPipelineInput').addEventListener('change', function(e) {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function(event) {
|
||||
processPipelineConfig(event.target.result);
|
||||
};
|
||||
reader.readAsText(e.target.files[0]);
|
||||
hideOrShowPipelineHeader();
|
||||
});
|
||||
|
||||
|
||||
|
||||
var saveBtn = document.getElementById('savePipelineBtn');
|
||||
|
||||
// Remove any existing event listeners
|
||||
saveBtn.removeEventListener('click', savePipeline);
|
||||
|
||||
// Add the event listener
|
||||
saveBtn.addEventListener('click', savePipeline);
|
||||
console.log("saveBtn", saveBtn)
|
||||
function savePipeline() {
|
||||
|
||||
if (validatePipeline() === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
var pipelineName = document.getElementById('pipelineName').value;
|
||||
let pipelineList = document.getElementById('pipelineList').children;
|
||||
let pipelineConfig = {
|
||||
"name": pipelineName,
|
||||
"pipeline": [],
|
||||
"_examples": {
|
||||
"outputDir": "{outputFolder}/{folderName}",
|
||||
"outputFileName": "{filename}-{pipelineName}-{date}-{time}"
|
||||
},
|
||||
"outputDir": "{outputFolder}",
|
||||
"outputFileName": "{filename}"
|
||||
};
|
||||
document.getElementById('pipelineSelect').addEventListener('change', function(e) {
|
||||
let selectedPipelineJson = e.target.value; // assuming the selected value is the JSON string of the pipeline config
|
||||
processPipelineConfig(selectedPipelineJson);
|
||||
});
|
||||
|
||||
for (let i = 0; i < pipelineList.length; i++) {
|
||||
let operationName = pipelineList[i].querySelector('.operationName').textContent;
|
||||
let parameters = operationSettings[operationName] || {};
|
||||
|
||||
parameters['fileInput'] = 'automated';
|
||||
|
||||
pipelineConfig.pipeline.push({
|
||||
"operation": operationName,
|
||||
"parameters": parameters
|
||||
});
|
||||
}
|
||||
console.log("Downloading..");
|
||||
let a = document.createElement('a');
|
||||
a.href = URL.createObjectURL(new Blob([JSON.stringify(pipelineConfig, null, 2)], {
|
||||
type: 'application/json'
|
||||
}));
|
||||
a.download = pipelineName + '.json';
|
||||
a.style.display = 'none';
|
||||
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
|
||||
async function processPipelineConfig(configString) {
|
||||
let pipelineConfig = JSON.parse(configString);
|
||||
let pipelineList = document.getElementById('pipelineList');
|
||||
|
||||
while (pipelineList.firstChild) {
|
||||
pipelineList.removeChild(pipelineList.firstChild);
|
||||
}
|
||||
document.getElementById('pipelineName').value = pipelineConfig.name
|
||||
for (const operationConfig of pipelineConfig.pipeline) {
|
||||
let operationsDropdown = document.getElementById('operationsDropdown');
|
||||
operationsDropdown.value = operationConfig.operation;
|
||||
operationSettings[operationConfig.operation] = operationConfig.parameters;
|
||||
|
||||
// assuming addOperation is async
|
||||
await new Promise((resolve) => {
|
||||
document.getElementById('addOperationBtn').addEventListener('click', resolve, { once: true });
|
||||
document.getElementById('addOperationBtn').click();
|
||||
});
|
||||
|
||||
let lastOperation = pipelineList.lastChild;
|
||||
|
||||
Object.keys(operationConfig.parameters).forEach(parameterName => {
|
||||
let input = document.getElementById(parameterName);
|
||||
if (input) {
|
||||
switch (input.type) {
|
||||
case 'checkbox':
|
||||
input.checked = operationConfig.parameters[parameterName];
|
||||
break;
|
||||
case 'number':
|
||||
input.value = operationConfig.parameters[parameterName].toString();
|
||||
break;
|
||||
case 'file':
|
||||
if (parameterName !== 'fileInput') {
|
||||
// Create a new file input element
|
||||
let newInput = document.createElement('input');
|
||||
newInput.type = 'file';
|
||||
newInput.id = parameterName;
|
||||
|
||||
// Add the new file input to the main page (change the selector according to your needs)
|
||||
document.querySelector('#main').appendChild(newInput);
|
||||
}
|
||||
break;
|
||||
case 'text':
|
||||
case 'textarea':
|
||||
default:
|
||||
input.value = JSON.stringify(operationConfig.parameters[parameterName]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('uploadPipelineBtn').addEventListener('click', function() {
|
||||
document.getElementById('uploadPipelineInput').click();
|
||||
});
|
||||
|
||||
document.getElementById('uploadPipelineInput').addEventListener('change', function(e) {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function(event) {
|
||||
processPipelineConfig(event.target.result);
|
||||
};
|
||||
reader.readAsText(e.target.files[0]);
|
||||
hideOrShowPipelineHeader();
|
||||
});
|
||||
|
||||
document.getElementById('pipelineSelect').addEventListener('change', function(e) {
|
||||
let selectedPipelineJson = e.target.value; // assuming the selected value is the JSON string of the pipeline config
|
||||
processPipelineConfig(selectedPipelineJson);
|
||||
});
|
||||
|
||||
|
||||
function hideOrShowPipelineHeader() {
|
||||
var pipelineHeader = document.getElementById('pipelineHeader');
|
||||
var pipelineList = document.getElementById('pipelineList');
|
||||
|
||||
if (pipelineList.children.length === 0) {
|
||||
// Hide the pipeline header if there are no items in the pipeline list
|
||||
pipelineHeader.style.display = 'none';
|
||||
} else {
|
||||
// Show the pipeline header if there are items in the pipeline list
|
||||
pipelineHeader.style.display = 'block';
|
||||
}
|
||||
function hideOrShowPipelineHeader() {
|
||||
var pipelineHeader = document.getElementById('pipelineHeader');
|
||||
var pipelineList = document.getElementById('pipelineList');
|
||||
|
||||
if (pipelineList.children.length === 0) {
|
||||
// Hide the pipeline header if there are no items in the pipeline list
|
||||
pipelineHeader.style.display = 'none';
|
||||
} else {
|
||||
// Show the pipeline header if there are items in the pipeline list
|
||||
pipelineHeader.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,23 +10,29 @@
|
|||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.bordered-box {
|
||||
border: 1px solid #ddd;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.center-element {
|
||||
width: 80%;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
}
|
||||
.element-margin {
|
||||
margin: 10px 0; /* Adjust this value to increase/decrease the margin as needed */
|
||||
}
|
||||
.bordered-box {
|
||||
border: 1px solid #ddd;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.center-element {
|
||||
width: 80%;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.element-margin {
|
||||
margin: 10px 0;
|
||||
/* Adjust this value to increase/decrease the margin as needed */
|
||||
}
|
||||
</style>
|
||||
|
||||
<script th:inline="javascript">
|
||||
const saveSettings = /*[[#{pipelineOptions.saveSettings}]]*/ '';
|
||||
</script>
|
||||
|
||||
<body>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
|
@ -35,154 +41,208 @@
|
|||
<br> <br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<h1>(Alpha) Pipeline Menu (Huge work in progress, very buggy!)</h1>
|
||||
<div class="bordered-box">
|
||||
<div class="text-end text-top">
|
||||
<button id="uploadPipelineBtn" class="btn btn-primary">Upload
|
||||
Custom</button>
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal"
|
||||
data-bs-target="#pipelineSettingsModal">Configure</button>
|
||||
</div>
|
||||
|
||||
<div class="center-element">
|
||||
<div class="element-margin">
|
||||
<select id="pipelineSelect" class="custom-select">
|
||||
<th:block th:each="config : ${pipelineConfigsWithNames}">
|
||||
<option th:value="${config.json}" th:text="${config.name}"></option>
|
||||
</th:block>
|
||||
</select>
|
||||
</div>
|
||||
<div class="element-margin">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=true)}"></div>
|
||||
</div>
|
||||
<div class="element-margin">
|
||||
<button class="btn btn-primary" id="submitConfigBtn">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1 th:text="#{pipeline.header}"></h1>
|
||||
<h2 th:text="#{WorkInProgess}"> </h2>
|
||||
<div class="bordered-box">
|
||||
<div class="text-end text-top">
|
||||
<button id="uploadPipelineBtn" class="btn btn-primary"
|
||||
th:text="#{pipeline.uploadButton}"></button>
|
||||
<button type="button" class="btn btn-primary"
|
||||
data-bs-toggle="modal" data-bs-target="#pipelineSettingsModal"
|
||||
th:text="#{pipeline.configureButton}"></button>
|
||||
|
||||
|
||||
<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>Does not work with multi-input functions yet (like merges)</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>fix initial config selected not loading</li>
|
||||
<li>Fix operation adding requering settings to be openned and saved instead of saving defaults</li>
|
||||
<li>multiInput support</li>
|
||||
<li>Translation support</li>
|
||||
<li>offline mode checks and testing</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 -->
|
||||
<div class="modal" id="pipelineSettingsModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content dark-card">
|
||||
|
||||
<!-- Modal Header -->
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-title">Pipeline Configuration</h2>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Modal body -->
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label for="pipelineName" class="form-label">Pipeline
|
||||
Name</label> <input type="text" id="pipelineName"
|
||||
class="form-control" placeholder="Enter pipeline name here">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<select id="operationsDropdown" class="form-select">
|
||||
<!-- Options will be dynamically populated here -->
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button id="addOperationBtn" class="btn btn-primary">Add
|
||||
operation</button>
|
||||
</div>
|
||||
<h3 id="pipelineHeader" style="display: none;">Pipeline:</h3>
|
||||
<ol id="pipelineList" class="list-group">
|
||||
<!-- Pipeline operations will be dynamically populated here -->
|
||||
</ol>
|
||||
<div id="pipelineSettingsContent">
|
||||
<!-- pipelineSettings will be dynamically populated here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal footer -->
|
||||
<div class="modal-footer">
|
||||
<button id="savePipelineBtn" class="btn btn-success">Download</button>
|
||||
<button id="validateButton" class="btn btn-success">Validate</button>
|
||||
<div class="btn-group">
|
||||
<input type="file" id="uploadPipelineInput" accept=".json"
|
||||
style="display: none;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="js/pipeline.js"></script>
|
||||
<div class="center-element">
|
||||
<div class="element-margin">
|
||||
<select id="pipelineSelect" class="custom-select">
|
||||
<option
|
||||
value="{"name":"Custom","pipeline":[],"_examples":{"outputDir":"{outputFolder}/{folderName}","outputFileName":"{filename}-{pipelineName}-{date}-{time}"},"outputDir":"{outputFolder}","outputFileName":"{filename}"}"
|
||||
th:text="#{pipeline.defaultOption}"></option>
|
||||
|
||||
|
||||
<th:block th:each="config : ${pipelineConfigsWithNames}">
|
||||
<option th:value="${config.json}" th:text="${config.name}"></option>
|
||||
</th:block>
|
||||
</select>
|
||||
</div>
|
||||
<div class="element-margin">
|
||||
<div
|
||||
th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=true)}"></div>
|
||||
</div>
|
||||
<div class="element-margin">
|
||||
<button class="btn btn-primary" id="submitConfigBtn"
|
||||
th:text="#{pipeline.submitButton}"></button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<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>Translation support</li>
|
||||
<li>Save to browser/Account</li>
|
||||
<li>offline mode checks and testing</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 -->
|
||||
<div class="modal" id="pipelineSettingsModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content dark-card">
|
||||
|
||||
<!-- Modal Header -->
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-title" th:text="#{pipelineOptions.header}"></h2>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<!-- Modal body -->
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label for="pipelineName" class="form-label"
|
||||
th:text="#{pipelineOptions.pipelineNameLabel}"></label> <input
|
||||
type="text" id="pipelineName" class="form-control"
|
||||
th:placeholder="#{pipelineOptions.pipelineNamePrompt}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<select id="operationsDropdown" class="form-select">
|
||||
<!-- Options will be dynamically populated here -->
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button id="addOperationBtn" class="btn btn-primary"
|
||||
th:text="#{pipelineOptions.addOperationButton}"></button>
|
||||
|
||||
</div>
|
||||
<h3 id="pipelineHeader" style="display: none;"
|
||||
th:text="#{pipelineOptions.pipelineHeader}"></h3>
|
||||
|
||||
<ol id="pipelineList" class="list-group">
|
||||
<!-- Pipeline operations will be dynamically populated here -->
|
||||
</ol>
|
||||
<div id="pipelineSettingsContent">
|
||||
<!-- pipelineSettings will be dynamically populated here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal footer -->
|
||||
<div class="modal-footer">
|
||||
<button id="savePipelineBtn" class="btn btn-success"
|
||||
th:text="#{pipelineOptions.saveButton}"></button>
|
||||
<button id="validateButton" class="btn btn-success"
|
||||
th:text="#{pipelineOptions.validateButton}"></button>
|
||||
|
||||
<div class="btn-group">
|
||||
<input type="file" id="uploadPipelineInput" accept=".json"
|
||||
style="display: none;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="js/pipeline.js"></script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
128
test.sh
Normal file
128
test.sh
Normal file
|
@ -0,0 +1,128 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 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+60))
|
||||
|
||||
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!"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to test a Docker Compose configuration
|
||||
test_compose() {
|
||||
local compose_file=$1
|
||||
local service_name=$2
|
||||
local status=0
|
||||
|
||||
echo "Testing $compose_file configuration..."
|
||||
|
||||
# Start up the Docker Compose service
|
||||
docker-compose -f "$compose_file" up -d
|
||||
|
||||
# Wait for the service to become healthy
|
||||
if check_health "$service_name" "$compose_file"; then
|
||||
echo "$service_name test passed."
|
||||
else
|
||||
echo "$service_name test failed."
|
||||
status=1
|
||||
fi
|
||||
|
||||
# Perform additional tests if needed
|
||||
|
||||
# Tear down the service
|
||||
docker-compose -f "$compose_file" down
|
||||
|
||||
return $status
|
||||
}
|
||||
|
||||
# Keep track of which tests passed and failed
|
||||
declare -a passed_tests
|
||||
declare -a failed_tests
|
||||
|
||||
run_tests() {
|
||||
local test_name=$1
|
||||
local compose_file=$2
|
||||
|
||||
if test_compose "$compose_file" "$test_name"; then
|
||||
passed_tests+=("$test_name")
|
||||
else
|
||||
failed_tests+=("$test_name")
|
||||
fi
|
||||
}
|
||||
|
||||
# Main testing routine
|
||||
main() {
|
||||
SECONDS=0
|
||||
|
||||
export DOCKER_ENABLE_SECURITY=false
|
||||
./gradlew clean build
|
||||
|
||||
# Building Docker images
|
||||
docker build --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile .
|
||||
docker build --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-lite -f ./Dockerfile-lite .
|
||||
docker build --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
|
||||
|
||||
# Test each configuration
|
||||
run_tests "Stirling-PDF-Ultra-Lite" "./exampleYmlFiles/docker-compose-latest-ultra-lite.yml"
|
||||
run_tests "Stirling-PDF-Lite" "./exampleYmlFiles/docker-compose-latest-lite.yml"
|
||||
run_tests "Stirling-PDF" "./exampleYmlFiles/docker-compose-latest.yml"
|
||||
|
||||
export DOCKER_ENABLE_SECURITY=true
|
||||
./gradlew clean build
|
||||
|
||||
# Building Docker images with security enabled
|
||||
docker build --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile .
|
||||
docker build --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-lite -f ./Dockerfile-lite .
|
||||
docker build --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
|
||||
|
||||
# Test each configuration with security
|
||||
run_tests "Stirling-PDF-Ultra-Lite-Security" "./exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml"
|
||||
run_tests "Stirling-PDF-Lite-Security" "./exampleYmlFiles/docker-compose-latest-lite-security.yml"
|
||||
run_tests "Stirling-PDF-Security" "./exampleYmlFiles/docker-compose-latest-security.yml"
|
||||
|
||||
# Report results
|
||||
echo "All tests completed in $SECONDS seconds."
|
||||
|
||||
|
||||
if [ ${#passed_tests[@]} -ne 0 ]; then
|
||||
echo "Passed tests:"
|
||||
fi
|
||||
for test in "${passed_tests[@]}"; do
|
||||
echo -e "\e[32m$test\e[0m" # Green color for passed tests
|
||||
done
|
||||
|
||||
if [ ${#failed_tests[@]} -ne 0 ]; then
|
||||
echo "Failed tests:"
|
||||
fi
|
||||
for test in "${failed_tests[@]}"; do
|
||||
echo -e "\e[31m$test\e[0m" # Red color for failed tests
|
||||
done
|
||||
|
||||
|
||||
|
||||
# Check if there are any failed tests and exit with an error code if so
|
||||
if [ ${#failed_tests[@]} -ne 0 ]; then
|
||||
echo "Some tests failed."
|
||||
exit 1
|
||||
else
|
||||
echo "All tests passed successfully."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
main
|
Loading…
Reference in a new issue