Add files via upload
This commit is contained in:
parent
5f3cba6037
commit
967846ec3a
9 changed files with 158 additions and 108 deletions
33
Jenkinsfile
vendored
Normal file
33
Jenkinsfile
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
stages {
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
sh 'chmod 755 gradlew'
|
||||||
|
sh './gradlew build'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Docker Build') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
|
||||||
|
def image = "frooodle/s-pdf:$appVersion"
|
||||||
|
sh "docker build -t $image ."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Docker Push') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
|
||||||
|
def image = "frooodle/s-pdf:$appVersion"
|
||||||
|
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
|
||||||
|
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
|
||||||
|
sh "docker push $image"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,7 @@
|
||||||
# Stirling-PDF (Made in 1 day with 100% ChatGPT, Even this readme!)
|
# Stirling-PDF
|
||||||
|
|
||||||
This is a locally hosted web application that allows you to perform various operations on PDF files, such as splitting and adding images.
|
This is a locally hosted web application that allows you to perform various operations on PDF files, such as splitting and adding images.
|
||||||
|
|
||||||
I will support and fix/add things to this if there is a demand [Discord](https://discord.gg/Cn8pWhQRxZ)
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Split PDFs into multiple files at specified page numbers or extract all pages as individual files.
|
- Split PDFs into multiple files at specified page numbers or extract all pages as individual files.
|
||||||
|
@ -33,8 +31,6 @@ Prerequisites
|
||||||
|
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
https://hub.docker.com/r/frooodle/s-pdf
|
|
||||||
|
|
||||||
docker pull frooodle/s-pdf
|
docker pull frooodle/s-pdf
|
||||||
|
|
||||||
docker run -p 8080:8080 frooodle/s-pdf
|
docker run -p 8080:8080 frooodle/s-pdf
|
||||||
|
@ -45,4 +41,4 @@ docker run -p 8080:8080 frooodle/s-pdf
|
||||||
2. Use the application by following the instructions on the website.
|
2. Use the application by following the instructions on the website.
|
||||||
|
|
||||||
## Note
|
## Note
|
||||||
The application is currently not thread-safe
|
The application is currently not thread-safe
|
|
@ -17,7 +17,7 @@ dependencies {
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
implementation 'org.apache.pdfbox:pdfbox:2.0.27'
|
implementation 'org.apache.pdfbox:pdfbox:2.0.27'
|
||||||
implementation 'log4j:log4j'
|
implementation 'org.apache.logging.log4j:log4j-core:2.19.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('test') {
|
tasks.named('test') {
|
||||||
|
|
|
@ -4,6 +4,10 @@ import java.io.IOException;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
@ -23,10 +27,26 @@ public class FromPDFController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/convert-from-pdf")
|
@PostMapping("/convert-from-pdf")
|
||||||
public byte[] convertToImage(@RequestParam("fileInput") MultipartFile file,
|
public ResponseEntity<byte[]> convertToImage(@RequestParam("fileInput") MultipartFile file,
|
||||||
@RequestParam("imageFormat") String imageFormat) throws IOException {
|
@RequestParam("imageFormat") String imageFormat) throws IOException {
|
||||||
byte[] pdfBytes = file.getBytes();
|
byte[] pdfBytes = file.getBytes();
|
||||||
return PdfUtils.convertFromPdf(pdfBytes, imageFormat);
|
//returns bytes for image
|
||||||
|
byte[] result = PdfUtils.convertFromPdf(pdfBytes, imageFormat.toLowerCase());
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.parseMediaType(getMediaType(imageFormat)));
|
||||||
|
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
|
||||||
|
ResponseEntity<byte[]> response = new ResponseEntity<>(result, headers, HttpStatus.OK);
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getMediaType(String imageFormat) {
|
||||||
|
if(imageFormat.equalsIgnoreCase("PNG"))
|
||||||
|
return "image/png";
|
||||||
|
else if(imageFormat.equalsIgnoreCase("JPEG"))
|
||||||
|
return "image/jpeg";
|
||||||
|
else if(imageFormat.equalsIgnoreCase("GIF"))
|
||||||
|
return "image/gif";
|
||||||
|
else
|
||||||
|
return "application/octet-stream";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +1,95 @@
|
||||||
<head th:fragment="head">
|
<head th:fragment="head">
|
||||||
<link rel="shortcut icon" href="favicon.svg">
|
<link rel="shortcut icon" href="favicon.svg">
|
||||||
<script
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
||||||
src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
|
||||||
<link rel="stylesheet"
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
||||||
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
|
<meta charset="UTF-8">
|
||||||
<script
|
|
||||||
src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
<link rel="stylesheet" th:href="@{dark-mode.css}" id="dark-mode-styles">
|
||||||
<meta charset="UTF-8">
|
<script>
|
||||||
|
function toggleDarkMode() {
|
||||||
<link rel="stylesheet" th:href="@{dark-mode.css}" id="dark-mode-styles">
|
var checkbox = document.getElementById("toggle-dark-mode");
|
||||||
<script>
|
var darkModeStyles = document.getElementById("dark-mode-styles");
|
||||||
function toggleDarkMode() {
|
if (checkbox.checked) {
|
||||||
var checkbox = document.getElementById("toggle-dark-mode");
|
localStorage.setItem("dark-mode", "on");
|
||||||
var darkModeStyles = document.getElementById("dark-mode-styles");
|
darkModeStyles.disabled = false;
|
||||||
if (checkbox.checked) {
|
} else {
|
||||||
localStorage.setItem("dark-mode", "on");
|
localStorage.setItem("dark-mode", "off");
|
||||||
darkModeStyles.disabled = false;
|
darkModeStyles.disabled = true;
|
||||||
} else {
|
}
|
||||||
localStorage.setItem("dark-mode", "off");
|
}
|
||||||
darkModeStyles.disabled = true;
|
$(document).ready(function () {
|
||||||
}
|
var darkModeStyles = document.getElementById("dark-mode-styles");
|
||||||
}
|
var checkbox = document.getElementById("toggle-dark-mode");
|
||||||
$(document).ready(function () {
|
if (localStorage.getItem("dark-mode") == "on") {
|
||||||
var darkModeStyles = document.getElementById("dark-mode-styles");
|
darkModeStyles.disabled = false;
|
||||||
var checkbox = document.getElementById("toggle-dark-mode");
|
checkbox.checked = true;
|
||||||
if(localStorage.getItem("dark-mode") == "on"){
|
}
|
||||||
darkModeStyles.disabled = false;
|
if (localStorage.getItem("dark-mode") == "off") {
|
||||||
checkbox.checked = true;
|
darkModeStyles.disabled = true;
|
||||||
}
|
checkbox.checked = false;
|
||||||
if(localStorage.getItem("dark-mode") == "off"){
|
}
|
||||||
darkModeStyles.disabled = true;
|
|
||||||
checkbox.checked = false;
|
});
|
||||||
}
|
</script>
|
||||||
|
<link rel="stylesheet" href="general.css">
|
||||||
});
|
</head>
|
||||||
</script>
|
|
||||||
<link rel="stylesheet" href="general.css">
|
<th:block th:fragment="filelist">
|
||||||
</head>
|
<div id="fileList"></div>
|
||||||
|
<div id="fileList2"></div>
|
||||||
<th:block th:fragment="filelist">
|
<script>
|
||||||
<div id="fileList"></div>
|
var input = document.getElementById("fileInput");
|
||||||
<div id="fileList2"></div>
|
var output = document.getElementById("fileList");
|
||||||
<script>
|
|
||||||
var input = document.getElementById("fileInput");
|
input.addEventListener("change", function () {
|
||||||
var output = document.getElementById("fileList");
|
var files = input.files;
|
||||||
|
var fileNames = "";
|
||||||
input.addEventListener("change", function() {
|
|
||||||
var files = input.files;
|
for (var i = 0; i < files.length; i++) {
|
||||||
var fileNames = "";
|
fileNames += (i + 1) + ". " + files[i].name + "<br>";
|
||||||
|
}
|
||||||
for (var i = 0; i < files.length; i++) {
|
|
||||||
fileNames += (i + 1) + ". " + files[i].name + "<br>";
|
output.innerHTML = fileNames;
|
||||||
}
|
});
|
||||||
|
|
||||||
output.innerHTML = fileNames;
|
</script>
|
||||||
});
|
<script>
|
||||||
|
var input2 = document.getElementById("fileInput2");
|
||||||
</script>
|
var output2 = document.getElementById("fileList2");
|
||||||
<script>
|
if (input2 != null && !input2) {
|
||||||
var input2 = document.getElementById("fileInput2");
|
input2.addEventListener("change", function () {
|
||||||
var output2 = document.getElementById("fileList2");
|
var files = input2.files;
|
||||||
if(input2 != null && !input2) {
|
var fileNames = "";
|
||||||
input2.addEventListener("change", function() {
|
|
||||||
var files = input2.files;
|
for (var i = 0; i < files.length; i++) {
|
||||||
var fileNames = "";
|
fileNames += (i + 1) + ". " + files[i].name + "<br>";
|
||||||
|
}
|
||||||
for (var i = 0; i < files.length; i++) {
|
|
||||||
fileNames += (i + 1) + ". " + files[i].name + "<br>";
|
output2.innerHTML = fileNames;
|
||||||
}
|
});
|
||||||
|
}
|
||||||
output2.innerHTML = fileNames;
|
</script>
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
<script>
|
||||||
</th:block>
|
if (dropContainer) {
|
||||||
|
dropContainer.ondragover = dropContainer.ondragenter = function (evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
dropContainer.ondrop = function (evt) {
|
||||||
|
if(fileInput) {
|
||||||
|
fileInput.files = evt.dataTransfer.files;
|
||||||
|
|
||||||
|
const dT = new DataTransfer();
|
||||||
|
dT.items.add(evt.dataTransfer.files[0]);
|
||||||
|
dT.items.add(evt.dataTransfer.files[3]);
|
||||||
|
fileInput.files = dT.files;
|
||||||
|
|
||||||
|
evt.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</th:block>
|
|
@ -15,7 +15,7 @@
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h2>PDF to img</h2>
|
<h2>PDF to img</h2>
|
||||||
<form method="post" enctype="multipart/form-data"
|
<form method="post" enctype="multipart/form-data"
|
||||||
th:action="@{/convert-to-image}">
|
th:action="@{/convert-from-pdf}">
|
||||||
<div class="custom-file">
|
<div class="custom-file">
|
||||||
<input type="file" class="custom-file-input" id="fileInput"
|
<input type="file" class="custom-file-input" id="fileInput"
|
||||||
name="fileInput" required> <label
|
name="fileInput" required> <label
|
||||||
|
|
|
@ -8,4 +8,4 @@
|
||||||
class="mx-1"> <i class="fab fa-docker fa-2x"></i>
|
class="mx-1"> <i class="fab fa-docker fa-2x"></i>
|
||||||
</a>
|
</a>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
|
@ -4,33 +4,16 @@
|
||||||
<th:block th:insert="~{common :: head}"></th:block>
|
<th:block th:insert="~{common :: head}"></th:block>
|
||||||
<title>S-PDF MergePDFs</title>
|
<title>S-PDF MergePDFs</title>
|
||||||
|
|
||||||
<script>
|
|
||||||
dropContainer.ondragover = dropContainer.ondragenter = function(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
dropContainer.ondrop = function(evt) {
|
|
||||||
// pretty simple -- but not for IE :(
|
|
||||||
fileInput.files = evt.dataTransfer.files;
|
|
||||||
|
|
||||||
// If you want to use some of the dropped files
|
|
||||||
const dT = new DataTransfer();
|
|
||||||
dT.items.add(evt.dataTransfer.files[0]);
|
|
||||||
dT.items.add(evt.dataTransfer.files[3]);
|
|
||||||
fileInput.files = dT.files;
|
|
||||||
|
|
||||||
evt.preventDefault();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div th:insert="~{navbar.html :: navbar}"></div>
|
<div th:insert="~{navbar.html :: navbar}"></div>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<div class="container">
|
<div class="container" id="dropContainer">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-6" id="dropContainer">
|
<div class="col-md-6" >
|
||||||
<h2>Merge multiple PDFs (2+)</h2>
|
<h2>Merge multiple PDFs (2+)</h2>
|
||||||
<form action="/merge-pdfs" method="post"
|
<form action="/merge-pdfs" method="post"
|
||||||
enctype="multipart/form-data">
|
enctype="multipart/form-data">
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<h1>Split PDF</h1>
|
<h1>Split PDF</h1>
|
||||||
<p>The numbers you select are the page number you wish to do a
|
<p>The numbers you select are the page number you wish to do a
|
||||||
split on</p>
|
split on</p>
|
||||||
<p>As such selecting 1,3,7-8 would split a 12 page document into
|
<p>As such selecting 1,3,7-8 would split a 10 page document into
|
||||||
6 separate PDFS with:</p>
|
6 separate PDFS with:</p>
|
||||||
<p>Document #1: Page 1</p>
|
<p>Document #1: Page 1</p>
|
||||||
<p>Document #2: Page 2 and 3</p>
|
<p>Document #2: Page 2 and 3</p>
|
||||||
|
|
Loading…
Reference in a new issue