Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a832198b4 | ||
|
|
2066bb2ae8 | ||
|
|
5d64c97406 | ||
|
|
d648c6d4b4 | ||
|
|
435bfa3b3f | ||
|
|
4d0135d7b7 | ||
|
|
5975928e89 |
25
Dockerfile
25
Dockerfile
@@ -1,5 +1,5 @@
|
|||||||
# Main stage
|
# Main stage
|
||||||
FROM alpine:20240329
|
FROM alpine:3.20.0
|
||||||
|
|
||||||
# Copy necessary files
|
# Copy necessary files
|
||||||
COPY scripts /scripts
|
COPY scripts /scripts
|
||||||
@@ -10,35 +10,33 @@ COPY build/libs/*.jar app.jar
|
|||||||
|
|
||||||
ARG VERSION_TAG
|
ARG VERSION_TAG
|
||||||
|
|
||||||
|
|
||||||
# Set Environment Variables
|
# Set Environment Variables
|
||||||
ENV DOCKER_ENABLE_SECURITY=false \
|
ENV DOCKER_ENABLE_SECURITY=false \
|
||||||
VERSION_TAG=$VERSION_TAG \
|
VERSION_TAG=$VERSION_TAG \
|
||||||
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" \
|
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" \
|
||||||
HOME=/home/stirlingpdfuser \
|
HOME=/home/stirlingpdfuser \
|
||||||
PUID=1000 \
|
PUID=1000 \
|
||||||
PGID=1000 \
|
PGID=1000 \
|
||||||
UMASK=022
|
UMASK=022
|
||||||
|
|
||||||
|
|
||||||
# JDK for app
|
# JDK for app
|
||||||
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
||||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
||||||
apk update && \
|
apk upgrade --no-cache -a && \
|
||||||
apk add --no-cache \
|
apk add --no-cache \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
tzdata \
|
tzdata \
|
||||||
tini \
|
tini \
|
||||||
openssl \
|
|
||||||
openssl-dev \
|
|
||||||
bash \
|
bash \
|
||||||
curl \
|
curl \
|
||||||
openjdk21-jre \
|
|
||||||
su-exec \
|
|
||||||
shadow \
|
shadow \
|
||||||
|
su-exec \
|
||||||
|
openssl \
|
||||||
|
openssl-dev \
|
||||||
|
openjdk21-jre \
|
||||||
# Doc conversion
|
# Doc conversion
|
||||||
libreoffice@testing \
|
libreoffice \
|
||||||
# pdftohtml
|
# pdftohtml
|
||||||
poppler-utils \
|
poppler-utils \
|
||||||
# OCR MY PDF (unpaper for descew and other advanced featues)
|
# OCR MY PDF (unpaper for descew and other advanced featues)
|
||||||
@@ -60,10 +58,9 @@ openssl-dev \
|
|||||||
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
||||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline && \
|
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline && \
|
||||||
chown stirlingpdfuser:stirlingpdfgroup /app.jar && \
|
chown stirlingpdfuser:stirlingpdfgroup /app.jar && \
|
||||||
tesseract --list-langs && \
|
tesseract --list-langs
|
||||||
rm -rf /var/cache/apk/*
|
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080/tcp
|
||||||
|
|
||||||
# Set user and run command
|
# Set user and run command
|
||||||
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# use alpine
|
# use alpine
|
||||||
FROM alpine:3.19.1
|
FROM alpine:3.20.0
|
||||||
|
|
||||||
ARG VERSION_TAG
|
ARG VERSION_TAG
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ ENV DOCKER_ENABLE_SECURITY=false \
|
|||||||
HOME=/home/stirlingpdfuser \
|
HOME=/home/stirlingpdfuser \
|
||||||
VERSION_TAG=$VERSION_TAG \
|
VERSION_TAG=$VERSION_TAG \
|
||||||
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" \
|
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" \
|
||||||
PUID=1000 \
|
PUID=1000 \
|
||||||
PGID=1000 \
|
PGID=1000 \
|
||||||
UMASK=022
|
UMASK=022
|
||||||
|
|
||||||
@@ -18,24 +18,23 @@ COPY scripts/init-without-ocr.sh /scripts/init-without-ocr.sh
|
|||||||
COPY pipeline /pipeline
|
COPY pipeline /pipeline
|
||||||
COPY build/libs/*.jar app.jar
|
COPY build/libs/*.jar app.jar
|
||||||
|
|
||||||
|
|
||||||
# Set up necessary directories and permissions
|
# Set up necessary directories and permissions
|
||||||
|
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||||
RUN mkdir /configs /logs /customFiles && \
|
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
||||||
chmod +x /scripts/*.sh && \
|
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
||||||
|
apk upgrade --no-cache -a && \
|
||||||
apk add --no-cache \
|
apk add --no-cache \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
tzdata \
|
tzdata \
|
||||||
tini \
|
tini \
|
||||||
bash \
|
bash \
|
||||||
curl \
|
curl \
|
||||||
su-exec \
|
|
||||||
shadow \
|
shadow \
|
||||||
|
su-exec \
|
||||||
openjdk21-jre && \
|
openjdk21-jre && \
|
||||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
|
||||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
|
||||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
|
||||||
# User permissions
|
# User permissions
|
||||||
|
mkdir /configs /logs /customFiles && \
|
||||||
|
chmod +x /scripts/*.sh && \
|
||||||
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
||||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /configs /customFiles /pipeline && \
|
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /configs /customFiles /pipeline && \
|
||||||
chown stirlingpdfuser:stirlingpdfgroup /app.jar
|
chown stirlingpdfuser:stirlingpdfgroup /app.jar
|
||||||
@@ -43,9 +42,8 @@ RUN mkdir /configs /logs /customFiles && \
|
|||||||
# Set environment variables
|
# Set environment variables
|
||||||
ENV ENDPOINTS_GROUPS_TO_REMOVE=CLI
|
ENV ENDPOINTS_GROUPS_TO_REMOVE=CLI
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080/tcp
|
||||||
|
|
||||||
ENTRYPOINT ["tini", "--", "/scripts/init-without-ocr.sh"]
|
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
|
ENTRYPOINT ["tini", "--", "/scripts/init-without-ocr.sh"]
|
||||||
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]
|
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ plugins {
|
|||||||
import com.github.jk1.license.render.*
|
import com.github.jk1.license.render.*
|
||||||
|
|
||||||
group = 'stirling.software'
|
group = 'stirling.software'
|
||||||
version = '0.24.5'
|
version = '0.24.6'
|
||||||
|
|
||||||
//17 is lowest but we support and recommend 21
|
//17 is lowest but we support and recommend 21
|
||||||
sourceCompatibility = '17'
|
sourceCompatibility = '17'
|
||||||
|
|||||||
@@ -8,7 +8,3 @@
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
.duplicate-warning {
|
|
||||||
color: red;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
@@ -47,12 +47,13 @@ function setupFileInput(chooser) {
|
|||||||
const dt = e.dataTransfer;
|
const dt = e.dataTransfer;
|
||||||
const files = dt.files;
|
const files = dt.files;
|
||||||
|
|
||||||
//Do not Update allFiles array here to prevent duplication, the change event listener will take care of that
|
|
||||||
const dataTransfer = new DataTransfer();
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
dataTransfer.items.add(files[i]);
|
allFiles.push(files[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dataTransfer = new DataTransfer();
|
||||||
|
allFiles.forEach((file) => dataTransfer.items.add(file));
|
||||||
|
|
||||||
const fileInput = document.getElementById(elementId);
|
const fileInput = document.getElementById(elementId);
|
||||||
fileInput.files = dataTransfer.files;
|
fileInput.files = dataTransfer.files;
|
||||||
|
|
||||||
@@ -79,40 +80,9 @@ function setupFileInput(chooser) {
|
|||||||
document.body.addEventListener("dragleave", dragleaveListener);
|
document.body.addEventListener("dragleave", dragleaveListener);
|
||||||
document.body.addEventListener("drop", dropListener);
|
document.body.addEventListener("drop", dropListener);
|
||||||
|
|
||||||
// When adding files
|
|
||||||
$("#" + elementId).on("change", function (e) {
|
$("#" + elementId).on("change", function (e) {
|
||||||
// Get newly Added Files
|
allFiles = Array.from(e.target.files);
|
||||||
const newFiles = Array.from(e.target.files).map(file => {
|
|
||||||
return {
|
|
||||||
file: file,
|
|
||||||
uniqueId: file.name + Date.now()// Assign a unique identifier to each file
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add new files to existing files
|
|
||||||
allFiles = [...allFiles, ...newFiles];
|
|
||||||
|
|
||||||
// Update the file input's files property
|
|
||||||
const dataTransfer = new DataTransfer();
|
|
||||||
allFiles.forEach((fileObj) => dataTransfer.items.add(fileObj.file));
|
|
||||||
e.target.files = dataTransfer.files;
|
|
||||||
|
|
||||||
handleFileInputChange(this);
|
handleFileInputChange(this);
|
||||||
|
|
||||||
// Call the displayFiles function with the allFiles array
|
|
||||||
displayFiles(allFiles)
|
|
||||||
// Dispatch a custom event with the allFiles array
|
|
||||||
var filesUpdated = new CustomEvent("filesUpdated", { detail: allFiles });
|
|
||||||
document.dispatchEvent(filesUpdated);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Listen for event of file being removed and then filter it out of the allFiles array
|
|
||||||
document.addEventListener("fileRemoved", function (e) {
|
|
||||||
const fileId = e.detail;
|
|
||||||
allFiles = allFiles.filter(fileObj => fileObj.uniqueId !== fileId); // Remove the file from the allFiles array using the unique identifier
|
|
||||||
// Dispatch a custom event with the allFiles array
|
|
||||||
var filesUpdated = new CustomEvent("filesUpdated", { detail: allFiles });
|
|
||||||
document.dispatchEvent(filesUpdated);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleFileInputChange(inputElement) {
|
function handleFileInputChange(inputElement) {
|
||||||
@@ -134,4 +104,9 @@ function setupFileInput(chooser) {
|
|||||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(pdfPrompt);
|
$(inputElement).siblings(".custom-file-label").addClass("selected").html(pdfPrompt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Listen for event of file being removed and the filter it out of the allFiles array
|
||||||
|
document.addEventListener("fileRemoved", function (e) {
|
||||||
|
const fileName = e.detail;
|
||||||
|
allFiles = allFiles.filter(file => file.name !== fileName);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,27 +2,15 @@ let currentSort = {
|
|||||||
field: null,
|
field: null,
|
||||||
descending: false,
|
descending: false,
|
||||||
};
|
};
|
||||||
//New Array to keep track of unique id
|
|
||||||
let filesWithUniqueId = [];
|
|
||||||
let processedFiles = [];
|
|
||||||
|
|
||||||
document.getElementById("fileInput-input").addEventListener("change", function () {
|
document.getElementById("fileInput-input").addEventListener("change", function () {
|
||||||
var files = Array.from(this.files).map(file => {
|
var files = this.files;
|
||||||
return {
|
|
||||||
file: file,
|
|
||||||
uniqueId: file.name + Date.now()
|
|
||||||
};
|
|
||||||
});
|
|
||||||
filesWithUniqueId = files;
|
|
||||||
displayFiles(files);
|
displayFiles(files);
|
||||||
});
|
});
|
||||||
//Get Files Updated Event from FileInput
|
|
||||||
document.addEventListener("filesUpdated", function (e) {
|
|
||||||
filesWithUniqueId = e.detail;
|
|
||||||
displayFiles(filesWithUniqueId);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FileList} files
|
||||||
|
*/
|
||||||
function displayFiles(files) {
|
function displayFiles(files) {
|
||||||
const list = document.getElementById("selectedFiles");
|
const list = document.getElementById("selectedFiles");
|
||||||
|
|
||||||
@@ -30,30 +18,12 @@ function displayFiles(files) {
|
|||||||
list.removeChild(list.firstChild);
|
list.removeChild(list.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the processedFiles array
|
|
||||||
processedFiles = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
const item = document.createElement("li");
|
const item = document.createElement("li");
|
||||||
item.className = "list-group-item";
|
item.className = "list-group-item";
|
||||||
item.dataset.id = files[i].uniqueId; // Assign the uniqueId to the list item
|
|
||||||
const fileNameDiv = document.createElement("div");
|
|
||||||
fileNameDiv.className = "filename";
|
|
||||||
fileNameDiv.textContent = files[i].file.name;
|
|
||||||
|
|
||||||
// Check for duplicates and add a warning if necessary
|
|
||||||
const duplicateFiles = files.filter(file => file.file.name === files[i].file.name);
|
|
||||||
if (duplicateFiles.length > 1) {
|
|
||||||
const warning = document.createElement("span");
|
|
||||||
warning.className = "duplicate-warning";
|
|
||||||
warning.textContent = "(Duplicate)";
|
|
||||||
fileNameDiv.appendChild(warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
item.innerHTML = `
|
item.innerHTML = `
|
||||||
<div class="d-flex justify-content-between align-items-center w-100">
|
<div class="d-flex justify-content-between align-items-center w-100">
|
||||||
${fileNameDiv.outerHTML}
|
<div class="filename">${files[i].name}</div>
|
||||||
<div class="arrows d-flex">
|
<div class="arrows d-flex">
|
||||||
<button class="btn btn-secondary move-up"><span>↑</span></button>
|
<button class="btn btn-secondary move-up"><span>↑</span></button>
|
||||||
<button class="btn btn-secondary move-down"><span>↓</span></button>
|
<button class="btn btn-secondary move-down"><span>↓</span></button>
|
||||||
@@ -63,6 +33,7 @@ function displayFiles(files) {
|
|||||||
`;
|
`;
|
||||||
list.appendChild(item);
|
list.appendChild(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
attachMoveButtons();
|
attachMoveButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,18 +66,16 @@ function attachMoveButtons() {
|
|||||||
|
|
||||||
var removeButtons = document.querySelectorAll(".remove-file");
|
var removeButtons = document.querySelectorAll(".remove-file");
|
||||||
for (var i = 0; i < removeButtons.length; i++) {
|
for (var i = 0; i < removeButtons.length; i++) {
|
||||||
// When the delete button is clicked
|
|
||||||
removeButtons[i].addEventListener("click", function (event) {
|
removeButtons[i].addEventListener("click", function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var parent = this.closest(".list-group-item");
|
var parent = this.closest(".list-group-item");
|
||||||
var fileId = parent.dataset.id; // Get the unique identifier of the file to be deleted
|
//Get name of removed file
|
||||||
|
var fileName = parent.querySelector(".filename").innerText;
|
||||||
parent.remove();
|
parent.remove();
|
||||||
// Remove the file from the filesWithUniqueId array
|
|
||||||
filesWithUniqueId = filesWithUniqueId.filter(fileObj => fileObj.uniqueId !== fileId);
|
|
||||||
updateFiles();
|
updateFiles();
|
||||||
// Dispatch a custom event with the unique identifier of the file to be deleted
|
//Dispatch a custom event with the name of the removed file
|
||||||
var fileRemoved = new CustomEvent("fileRemoved", { detail: fileId });
|
var event = new CustomEvent("fileRemoved", { detail: fileName });
|
||||||
document.dispatchEvent(fileRemoved);
|
document.dispatchEvent(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,29 +103,30 @@ document.getElementById("sortByDateBtn").addEventListener("click", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function sortFiles(comparator) {
|
function sortFiles(comparator) {
|
||||||
// Sort the filesWithUniqueId array
|
// Convert FileList to array and sort
|
||||||
const sortedFilesArray = filesWithUniqueId.sort((a, b) => comparator(a.file, b.file));
|
const sortedFilesArray = Array.from(document.getElementById("fileInput-input").files).sort(comparator);
|
||||||
|
|
||||||
// Refresh displayed list
|
// Refresh displayed list
|
||||||
displayFiles(sortedFilesArray);
|
displayFiles(sortedFilesArray);
|
||||||
|
|
||||||
// Update the files property
|
// Update the files property
|
||||||
const dataTransfer = new DataTransfer();
|
const dataTransfer = new DataTransfer();
|
||||||
sortedFilesArray.forEach((fileObj) => dataTransfer.items.add(fileObj.file));
|
sortedFilesArray.forEach((file) => dataTransfer.items.add(file));
|
||||||
document.getElementById("fileInput-input").files = dataTransfer.files;
|
document.getElementById("fileInput-input").files = dataTransfer.files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function updateFiles() {
|
function updateFiles() {
|
||||||
var dataTransfer = new DataTransfer();
|
var dataTransfer = new DataTransfer();
|
||||||
var liElements = document.querySelectorAll("#selectedFiles li");
|
var liElements = document.querySelectorAll("#selectedFiles li");
|
||||||
|
const files = document.getElementById("fileInput-input").files;
|
||||||
|
|
||||||
for (var i = 0; i < liElements.length; i++) {
|
for (var i = 0; i < liElements.length; i++) {
|
||||||
var fileIdFromList = liElements[i].dataset.id; // Get the unique identifier from the list item
|
var fileNameFromList = liElements[i].querySelector(".filename").innerText;
|
||||||
for (var j = 0; j < filesWithUniqueId.length; j++) {
|
var fileFromFiles;
|
||||||
var fileObj = filesWithUniqueId[j];
|
for (var j = 0; j < files.length; j++) {
|
||||||
if (fileObj.uniqueId === fileIdFromList) {
|
var file = files[j];
|
||||||
dataTransfer.items.add(fileObj.file);
|
if (file.name === fileNameFromList) {
|
||||||
|
dataTransfer.items.add(file);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user