sign changes min size, lite docker, merge fix #172
This commit is contained in:
parent
ecba6461df
commit
04032c0dfe
11 changed files with 124 additions and 85 deletions
69
.github/workflows/push-docker.yml
vendored
69
.github/workflows/push-docker.yml
vendored
|
@ -8,8 +8,14 @@ on:
|
|||
- main
|
||||
jobs:
|
||||
push:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
config: [
|
||||
{ dockerfile: "./Dockerfile", tagSuffix: "" },
|
||||
{ dockerfile: "./Dockerfile-ultra-lite", tagSuffix: "-ultra-lite" },
|
||||
{ dockerfile: "./Dockerfile-lite", tagSuffix: "-lite" }
|
||||
]
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v3.5.2
|
||||
|
@ -46,17 +52,10 @@ jobs:
|
|||
username: ${{ github.actor }}
|
||||
password: ${{ github.token }}
|
||||
|
||||
- name: Generate tags
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4.4.0
|
||||
with:
|
||||
images: |
|
||||
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
|
||||
ghcr.io/${{ github.repository_owner }}/s-pdf
|
||||
tags: |
|
||||
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }},enable=${{ github.ref == 'refs/heads/master' }}
|
||||
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
|
||||
type=raw,value=alpha,enable=${{ github.ref == 'refs/heads/main' }}
|
||||
- name: Convert repository owner to lowercase
|
||||
id: repoowner
|
||||
run: echo "::set-output name=lowercase::$(echo ${{ github.repository_owner }} | awk '{print tolower($0)}')"
|
||||
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2.1.0
|
||||
|
@ -64,11 +63,24 @@ jobs:
|
|||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2.5.0
|
||||
|
||||
- name: Build and push main Dockerfile
|
||||
|
||||
- name: Generate tags
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4.4.0
|
||||
with:
|
||||
images: |
|
||||
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
|
||||
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf
|
||||
tags: |
|
||||
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}${{ matrix.config.tagSuffix }},enable=${{ github.ref == 'refs/heads/master' }}
|
||||
type=raw,value=latest${{ matrix.config.tagSuffix }},enable=${{ github.ref == 'refs/heads/master' }}
|
||||
type=raw,value=alpha,enable=${{ github.ref == 'refs/heads/main' }}
|
||||
|
||||
- name: Build and push Dockerfile
|
||||
uses: docker/build-push-action@v4.0.0
|
||||
with:
|
||||
context: .
|
||||
dockerfile: ./Dockerfile
|
||||
dockerfile: ${{ matrix.config.dockerfile }}
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
@ -76,32 +88,3 @@ jobs:
|
|||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
|
||||
- name: Generate tags
|
||||
id: meta2
|
||||
uses: docker/metadata-action@v4.4.0
|
||||
with:
|
||||
images: |
|
||||
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
|
||||
ghcr.io/${{ github.repository_owner }}/s-pdf
|
||||
tags: |
|
||||
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-ultra-light,enable=${{ github.ref == 'refs/heads/master' }}
|
||||
type=raw,value=latest-ultra-light,enable=${{ github.ref == 'refs/heads/master' }}
|
||||
type=raw,value=alpha-ultra-light,enable=${{ github.ref == 'refs/heads/main' }}
|
||||
|
||||
- name: Convert repository owner to lowercase
|
||||
id: repoowner
|
||||
run: echo "::set-output name=lowercase::$(echo ${{ github.repository_owner }} | awk '{print tolower($0)}')"
|
||||
|
||||
- name: Build and push Dockerfile-ultralite
|
||||
uses: docker/build-push-action@v4.0.0
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile-ultralite
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
tags: ${{ steps.meta2.outputs.tags }}
|
||||
labels: ${{ steps.meta2.outputs.labels }}
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
|
||||
|
||||
|
|
23
Dockerfile-lite
Normal file
23
Dockerfile-lite
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Build jbig2enc in a separate stage
|
||||
FROM bellsoft/liberica-openjdk-debian:17
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libreoffice-core-nogui \
|
||||
libreoffice-common \
|
||||
libreoffice-writer-nogui \
|
||||
libreoffice-calc-nogui \
|
||||
libreoffice-impress-nogui \
|
||||
unoconv && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy the application JAR file
|
||||
COPY build/libs/*.jar app.jar
|
||||
|
||||
# Expose the application port
|
||||
EXPOSE 8080
|
||||
|
||||
# Set environment variables
|
||||
ENV GROUPS_TO_REMOVE=Python,OpenCV,OCRmyPDF
|
||||
|
||||
# Run the application
|
||||
CMD ["java", "-jar", "/app.jar"]
|
|
@ -1,5 +1,5 @@
|
|||
# Build jbig2enc in a separate stage
|
||||
FROM openjdk:17-jdk-slim
|
||||
FROM bellsoft/liberica-openjdk-alpine:17
|
||||
|
||||
# Copy the application JAR file
|
||||
COPY build/libs/*.jar app.jar
|
|
@ -1,5 +1,5 @@
|
|||
# Main stage
|
||||
FROM openjdk:17-jdk-slim AS base
|
||||
FROM bellsoft/liberica-openjdk-debian:17 AS base
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libreoffice-core-nogui \
|
||||
|
|
|
@ -16,11 +16,19 @@ def is_blank_image(image_path, threshold=10, white_percent=99, white_value=255,
|
|||
_, thresholded_image = cv2.threshold(blurred_image, white_value - threshold, white_value, cv2.THRESH_BINARY)
|
||||
|
||||
# Calculate the percentage of white pixels in the thresholded image
|
||||
white_pixels = np.sum(thresholded_image == white_value)
|
||||
white_pixels = 0
|
||||
total_pixels = thresholded_image.size
|
||||
white_pixel_percentage = (white_pixels / total_pixels) * 100
|
||||
for i in range(0, thresholded_image.shape[0], 2):
|
||||
for j in range(0, thresholded_image.shape[1], 2):
|
||||
if thresholded_image[i, j] == white_value:
|
||||
white_pixels += 1
|
||||
white_pixel_percentage = (white_pixels / (i * thresholded_image.shape[1] + j + 1)) * 100
|
||||
if white_pixel_percentage < white_percent:
|
||||
return False
|
||||
|
||||
print(f"Page has white pixel percent of {white_pixel_percentage}")
|
||||
return white_pixel_percentage > white_percent
|
||||
return True
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -20,12 +20,14 @@ public class EndpointConfiguration {
|
|||
}
|
||||
|
||||
public void enableEndpoint(String endpoint) {
|
||||
endpointStatuses.put(endpoint, true);
|
||||
endpointStatuses.put(endpoint, true);
|
||||
}
|
||||
|
||||
public void disableEndpoint(String endpoint) {
|
||||
logger.info("Disabling {}", endpoint);
|
||||
endpointStatuses.put(endpoint, false);
|
||||
if(!endpointStatuses.containsKey(endpoint) || endpointStatuses.get(endpoint) != false) {
|
||||
logger.info("Disabling {}", endpoint);
|
||||
endpointStatuses.put(endpoint, false);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEndpointEnabled(String endpoint) {
|
||||
|
|
|
@ -74,7 +74,9 @@ public class OtherWebController {
|
|||
@Hidden
|
||||
public ModelAndView ocrPdfPage() {
|
||||
ModelAndView modelAndView = new ModelAndView("other/ocr-pdf");
|
||||
modelAndView.addObject("languages", getAvailableTesseractLanguages());
|
||||
List<String> languages = getAvailableTesseractLanguages();
|
||||
Collections.sort(languages);
|
||||
modelAndView.addObject("languages", languages);
|
||||
modelAndView.addObject("currentPage", "ocr-pdf");
|
||||
return modelAndView;
|
||||
}
|
||||
|
|
|
@ -19,12 +19,13 @@ $(document).ready(function() {
|
|||
$('#submitBtn').text('Processing...');
|
||||
|
||||
try {
|
||||
if (override === 'multi' || files.length > 1 && override !== 'single') {
|
||||
await submitMultiPdfForm(url, files);
|
||||
} else {
|
||||
await handleSingleDownload(url, formData);
|
||||
if(remoteCall === true) {
|
||||
if (override === 'multi' || (!multiple && files.length > 1) && override !== 'single' ) {
|
||||
await submitMultiPdfForm(url, files);
|
||||
} else {
|
||||
await handleSingleDownload(url, formData);
|
||||
}
|
||||
}
|
||||
|
||||
$('#submitBtn').text(originalButtonText);
|
||||
} catch (error) {
|
||||
handleDownloadError(error);
|
||||
|
|
|
@ -25,33 +25,50 @@ const DraggableUtils = {
|
|||
},
|
||||
})
|
||||
.resizable({
|
||||
edges: { left: true, right: true, bottom: true, top: true },
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
var target = event.target
|
||||
var x = (parseFloat(target.getAttribute('data-x')) || 0)
|
||||
var y = (parseFloat(target.getAttribute('data-y')) || 0)
|
||||
edges: { left: true, right: true, bottom: true, top: true },
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
var target = event.target
|
||||
var x = (parseFloat(target.getAttribute('data-x')) || 0)
|
||||
var y = (parseFloat(target.getAttribute('data-y')) || 0)
|
||||
|
||||
// update the element's style
|
||||
target.style.width = event.rect.width + 'px'
|
||||
target.style.height = event.rect.height + 'px'
|
||||
// check if control key is pressed
|
||||
if (event.ctrlKey) {
|
||||
const aspectRatio = target.offsetWidth / target.offsetHeight;
|
||||
// preserve aspect ratio
|
||||
let width = event.rect.width;
|
||||
let height = event.rect.height;
|
||||
|
||||
// translate when resizing from top or left edges
|
||||
x += event.deltaRect.left
|
||||
y += event.deltaRect.top
|
||||
if (Math.abs(event.deltaRect.width) >= Math.abs(event.deltaRect.height)) {
|
||||
height = width / aspectRatio;
|
||||
} else {
|
||||
width = height * aspectRatio;
|
||||
}
|
||||
|
||||
target.style.transform = 'translate(' + x + 'px,' + y + 'px)'
|
||||
event.rect.width = width;
|
||||
event.rect.height = height;
|
||||
}
|
||||
|
||||
target.setAttribute('data-x', x)
|
||||
target.setAttribute('data-y', y)
|
||||
target.textContent = Math.round(event.rect.width) + '\u00D7' + Math.round(event.rect.height)
|
||||
target.style.width = event.rect.width + 'px'
|
||||
target.style.height = event.rect.height + 'px'
|
||||
|
||||
// translate when resizing from top or left edges
|
||||
x += event.deltaRect.left
|
||||
y += event.deltaRect.top
|
||||
|
||||
target.style.transform = 'translate(' + x + 'px,' + y + 'px)'
|
||||
|
||||
target.setAttribute('data-x', x)
|
||||
target.setAttribute('data-y', y)
|
||||
target.textContent = Math.round(event.rect.width) + '\u00D7' + Math.round(event.rect.height)
|
||||
|
||||
this.onInteraction(target);
|
||||
},
|
||||
},
|
||||
|
||||
this.onInteraction(target);
|
||||
},
|
||||
},
|
||||
modifiers: [
|
||||
interact.modifiers.restrictSize({
|
||||
min: { width: 50, height: 50 },
|
||||
min: { width: 5, height: 5 },
|
||||
}),
|
||||
],
|
||||
inertia: true,
|
||||
|
|
|
@ -90,9 +90,11 @@
|
|||
</dialog>
|
||||
</th:block>
|
||||
|
||||
<th:block th:fragment="fileSelector(name, multiple)" th:with="accept=${accept} ?: '*/*', inputText=${inputText} ?: #{pdfPrompt}, remoteCall=${remoteCall} ?: 'true', notRequired=${notRequired} ?: false">
|
||||
<th:block th:fragment="fileSelector(name, multiple)" th:with="accept=${accept} ?: '*/*', inputText=${inputText} ?: #{pdfPrompt}, remoteCall=${remoteCall} ?: true, notRequired=${notRequired} ?: false">
|
||||
<script th:inline="javascript">
|
||||
const pdfPasswordPrompt =/*[[#{error.pdfPassword}]]*/ '';
|
||||
const multiple = [[${multiple}]] || false;
|
||||
const remoteCall = [[${remoteCall}]] || true;
|
||||
</script>
|
||||
<script src="js/downloader.js"></script>
|
||||
|
||||
|
|
|
@ -130,12 +130,13 @@
|
|||
// When zoomed out to less than 100%, for some very strange reason,
|
||||
// some browsers report devicePixelRatio as less than 1
|
||||
// and only part of the canvas is cleared then.
|
||||
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
||||
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
||||
var additionalFactor = 10;
|
||||
|
||||
signaturePadCanvas.width = signaturePadCanvas.offsetWidth * ratio * additionalFactor;
|
||||
signaturePadCanvas.height = signaturePadCanvas.offsetHeight * ratio * additionalFactor;
|
||||
signaturePadCanvas.getContext("2d").scale(ratio * additionalFactor, ratio * additionalFactor);
|
||||
|
||||
// This part causes the canvas to be cleared
|
||||
signaturePadCanvas.width = signaturePadCanvas.offsetWidth * ratio;
|
||||
signaturePadCanvas.height = signaturePadCanvas.offsetHeight * ratio;
|
||||
signaturePadCanvas.getContext("2d").scale(ratio, ratio);
|
||||
|
||||
// This library does not listen for canvas changes, so after the canvas is automatically
|
||||
// cleared by the browser, SignaturePad#isEmpty might still return false, even though the
|
||||
|
|
Loading…
Reference in a new issue