1
0
mirror of https://github.com/Stirling-Tools/Stirling-PDF.git synced 2024-11-23 15:21:25 +01:00

Add files via upload

This commit is contained in:
Anthony Stirling 2023-01-28 10:00:32 +00:00 committed by GitHub
parent 5f3cba6037
commit 967846ec3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 158 additions and 108 deletions

33
Jenkinsfile vendored Normal file
View 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"
}
}
}
}
}
}

View File

@ -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.
I will support and fix/add things to this if there is a demand [Discord](https://discord.gg/Cn8pWhQRxZ)
## Features
- Split PDFs into multiple files at specified page numbers or extract all pages as individual files.
@ -33,8 +31,6 @@ Prerequisites
### Docker
https://hub.docker.com/r/frooodle/s-pdf
docker pull 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.
## Note
The application is currently not thread-safe
The application is currently not thread-safe

View File

@ -17,7 +17,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.apache.pdfbox:pdfbox:2.0.27'
implementation 'log4j:log4j'
implementation 'org.apache.logging.log4j:log4j-core:2.19.0'
}
tasks.named('test') {

View File

@ -4,6 +4,10 @@ import java.io.IOException;
import org.slf4j.Logger;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -23,10 +27,26 @@ public class FromPDFController {
}
@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 {
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";
}
}

View File

@ -1,77 +1,95 @@
<head th:fragment="head">
<link rel="shortcut icon" href="favicon.svg">
<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">
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<meta charset="UTF-8">
<link rel="stylesheet" th:href="@{dark-mode.css}" id="dark-mode-styles">
<script>
function toggleDarkMode() {
var checkbox = document.getElementById("toggle-dark-mode");
var darkModeStyles = document.getElementById("dark-mode-styles");
if (checkbox.checked) {
localStorage.setItem("dark-mode", "on");
darkModeStyles.disabled = false;
} 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");
if(localStorage.getItem("dark-mode") == "on"){
darkModeStyles.disabled = false;
checkbox.checked = true;
}
if(localStorage.getItem("dark-mode") == "off"){
darkModeStyles.disabled = true;
checkbox.checked = false;
}
});
</script>
<link rel="stylesheet" href="general.css">
</head>
<th:block th:fragment="filelist">
<div id="fileList"></div>
<div id="fileList2"></div>
<script>
var input = document.getElementById("fileInput");
var output = document.getElementById("fileList");
input.addEventListener("change", function() {
var files = input.files;
var fileNames = "";
for (var i = 0; i < files.length; i++) {
fileNames += (i + 1) + ". " + files[i].name + "<br>";
}
output.innerHTML = fileNames;
});
</script>
<script>
var input2 = document.getElementById("fileInput2");
var output2 = document.getElementById("fileList2");
if(input2 != null && !input2) {
input2.addEventListener("change", function() {
var files = input2.files;
var fileNames = "";
for (var i = 0; i < files.length; i++) {
fileNames += (i + 1) + ". " + files[i].name + "<br>";
}
output2.innerHTML = fileNames;
});
}
</script>
</th:block>
<head th:fragment="head">
<link rel="shortcut icon" href="favicon.svg">
<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">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<meta charset="UTF-8">
<link rel="stylesheet" th:href="@{dark-mode.css}" id="dark-mode-styles">
<script>
function toggleDarkMode() {
var checkbox = document.getElementById("toggle-dark-mode");
var darkModeStyles = document.getElementById("dark-mode-styles");
if (checkbox.checked) {
localStorage.setItem("dark-mode", "on");
darkModeStyles.disabled = false;
} 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");
if (localStorage.getItem("dark-mode") == "on") {
darkModeStyles.disabled = false;
checkbox.checked = true;
}
if (localStorage.getItem("dark-mode") == "off") {
darkModeStyles.disabled = true;
checkbox.checked = false;
}
});
</script>
<link rel="stylesheet" href="general.css">
</head>
<th:block th:fragment="filelist">
<div id="fileList"></div>
<div id="fileList2"></div>
<script>
var input = document.getElementById("fileInput");
var output = document.getElementById("fileList");
input.addEventListener("change", function () {
var files = input.files;
var fileNames = "";
for (var i = 0; i < files.length; i++) {
fileNames += (i + 1) + ". " + files[i].name + "<br>";
}
output.innerHTML = fileNames;
});
</script>
<script>
var input2 = document.getElementById("fileInput2");
var output2 = document.getElementById("fileList2");
if (input2 != null && !input2) {
input2.addEventListener("change", function () {
var files = input2.files;
var fileNames = "";
for (var i = 0; i < files.length; i++) {
fileNames += (i + 1) + ". " + files[i].name + "<br>";
}
output2.innerHTML = fileNames;
});
}
</script>
<script>
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>

View File

@ -15,7 +15,7 @@
<div class="col-md-6">
<h2>PDF to img</h2>
<form method="post" enctype="multipart/form-data"
th:action="@{/convert-to-image}">
th:action="@{/convert-from-pdf}">
<div class="custom-file">
<input type="file" class="custom-file-input" id="fileInput"
name="fileInput" required> <label

View File

@ -8,4 +8,4 @@
class="mx-1"> <i class="fab fa-docker fa-2x"></i>
</a>
</footer>
</div>
</div>

View File

@ -4,33 +4,16 @@
<th:block th:insert="~{common :: head}"></th:block>
<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>
<body>
<div th:insert="~{navbar.html :: navbar}"></div>
<br>
<br>
<div class="container">
<div class="container" id="dropContainer">
<div class="row justify-content-center">
<div class="col-md-6" id="dropContainer">
<div class="col-md-6" >
<h2>Merge multiple PDFs (2+)</h2>
<form action="/merge-pdfs" method="post"
enctype="multipart/form-data">

View File

@ -15,7 +15,7 @@
<h1>Split PDF</h1>
<p>The numbers you select are the page number you wish to do a
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>
<p>Document #1: Page 1</p>
<p>Document #2: Page 2 and 3</p>