mirror of
				https://github.com/Frooodle/Stirling-PDF.git
				synced 2025-10-25 11:17:28 +02:00 
			
		
		
		
	Merge branch 'cleanups' of https://github.com/Frooodle/Stirling-PDF into cleanups
This commit is contained in:
		
						commit
						12d457e3ee
					
				| @ -1,8 +1,10 @@ | ||||
| package stirling.software.SPDF.controller.web; | ||||
| 
 | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.stereotype.Controller; | ||||
| import org.springframework.ui.Model; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.ResponseBody; | ||||
| 
 | ||||
| import io.swagger.v3.oas.annotations.Hidden; | ||||
| 
 | ||||
| @ -67,14 +69,26 @@ public class GeneralWebController { | ||||
|         return "split-pdfs"; | ||||
|     } | ||||
|      | ||||
|      | ||||
|      | ||||
|      | ||||
|     @GetMapping("/sign") | ||||
|     @Hidden | ||||
|     public String signForm(Model model) { | ||||
|         model.addAttribute("currentPage", "sign"); | ||||
|         return "sign"; | ||||
|     } | ||||
| 
 | ||||
|     @GetMapping(value = "/robots.txt", produces = MediaType.TEXT_PLAIN_VALUE) | ||||
|     @ResponseBody | ||||
|     public String getRobotsTxt() { | ||||
|         String allowGoogleVisibility = System.getProperty("ALLOW_GOOGLE_VISABILITY"); | ||||
|         if (allowGoogleVisibility == null) | ||||
|             allowGoogleVisibility = System.getenv("ALLOW_GOOGLE_VISABILITY"); | ||||
|         if (allowGoogleVisibility == null) | ||||
|             allowGoogleVisibility = "true"; | ||||
|         if (Boolean.parseBoolean(allowGoogleVisibility)) { | ||||
|             return "User-agent: Googlebot\nAllow: /\n\nUser-agent: *\nDisallow: /"; | ||||
|         } else { | ||||
|             return "User-agent: Googlebot\nDisallow: /\n\nUser-agent: *\nDisallow: /"; | ||||
|         } | ||||
|     } | ||||
|      | ||||
| } | ||||
|  | ||||
| @ -53,6 +53,12 @@ public class OtherWebController { | ||||
|         return "other/change-metadata"; | ||||
|     } | ||||
|      | ||||
|     @GetMapping("/compare") | ||||
|     @Hidden | ||||
|     public String compareForm(Model model) { | ||||
|         model.addAttribute("currentPage", "compare"); | ||||
|         return "other/compare"; | ||||
|     } | ||||
|      | ||||
|     public List<String> getAvailableTesseractLanguages() { | ||||
|         String tessdataDir = "/usr/share/tesseract-ocr/4.00/tessdata"; | ||||
|  | ||||
| @ -117,8 +117,25 @@ home.flatten.desc=Remove all interactive elements and forms from a PDF | ||||
| home.repair.title=Repair | ||||
| home.repair.desc=Tries to repair a corrupt/broken PDF | ||||
| 
 | ||||
| downloadPdf=Download PDF | ||||
| text=Text | ||||
| font=Font | ||||
| 
 | ||||
| sign.title=Sign | ||||
| sign.header=Sign PDFs | ||||
| sign.upload=Upload Image | ||||
| sign.draw=Draw Signature | ||||
| sign.text=Text Input | ||||
| sign.clear=Clear | ||||
| sign.add=Add | ||||
| 
 | ||||
| repair.title=Repair | ||||
| repair.header=Repair PDFs | ||||
| repair.submit=Repair | ||||
| 
 | ||||
| flatten.title=Flatten | ||||
| flatten.header=Flatten PDFs | ||||
| flatten.submit=Flatten | ||||
| 
 | ||||
| ScannerImageSplit.selectText.1=Angle Threshold: | ||||
| ScannerImageSplit.selectText.2=Sets the minimum absolute angle required for the image to be rotated (default: 10). | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/static/fonts/Estonia.woff2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/static/fonts/Estonia.woff2
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/static/fonts/Tangerine.woff2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/static/fonts/Tangerine.woff2
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										3
									
								
								src/main/resources/static/js/interact.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/main/resources/static/js/interact.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										6
									
								
								src/main/resources/static/js/signature_pad.umd.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/main/resources/static/js/signature_pad.umd.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										135
									
								
								src/main/resources/templates/other/compare.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								src/main/resources/templates/other/compare.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,135 @@ | ||||
| <!DOCTYPE html> | ||||
| <html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org"> | ||||
| 
 | ||||
| 
 | ||||
| <th:block th:insert="~{fragments/common :: head(title=#{repair.title})}"></th:block> | ||||
| 
 | ||||
| 
 | ||||
| <body> | ||||
|     <div id="page-container"> | ||||
|         <div id="content-wrap"> | ||||
|             <div th:insert="~{fragments/navbar.html :: navbar}"></div> | ||||
|             <br> <br> | ||||
|             <div class="container"> | ||||
|                 <div class="row justify-content-center"> | ||||
|                     <div class="col-md-6"> | ||||
|                         <h2 th:text="#{repair.header}"></h2> | ||||
|                           | ||||
|                         <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div> | ||||
|                         <div th:replace="~{fragments/common :: fileSelector(name='fileInput2', multiple=false, accept='application/pdf')}"></div> | ||||
|                         <button onclick="comparePDFs()">Compare</button> | ||||
|                         <div id="result"></div> | ||||
|                         <script> | ||||
|                         async function comparePDFs() { | ||||
|                             const file1 = document.getElementById("fileInput-input").files[0]; | ||||
|                             const file2 = document.getElementById("fileInput2-input").files[0]; | ||||
| 
 | ||||
|                             if (!file1 || !file2) { | ||||
|                                 console.error("Please select two PDF files to compare"); | ||||
|                                 return; | ||||
|                             } | ||||
|                              | ||||
|                             const [pdf1, pdf2] = await Promise.all([ | ||||
|                                 pdfjsLib.getDocument(URL.createObjectURL(file1)).promise, | ||||
|                                 pdfjsLib.getDocument(URL.createObjectURL(file2)).promise | ||||
|                             ]); | ||||
| 
 | ||||
|                             const extractText = async (pdf) => { | ||||
|                                 const pages = []; | ||||
|                                 for (let i = 1; i <= pdf.numPages; i++) { | ||||
|                                     const page = await pdf.getPage(i); | ||||
|                                     const content = await page.getTextContent(); | ||||
|                                     const strings = content.items.map(item => item.str); | ||||
|                                     pages.push(strings.join("")); | ||||
|                                 } | ||||
|                                 return pages.join("\n"); | ||||
|                             }; | ||||
| 
 | ||||
|                             const [text1, text2] = await Promise.all([ | ||||
|                                 extractText(pdf1), | ||||
|                                 extractText(pdf2) | ||||
|                             ]); | ||||
| 
 | ||||
|                             const diff = (text1, text2) => { | ||||
|                                 const lines1 = text1.split("\n"); | ||||
|                                 const lines2 = text2.split("\n"); | ||||
| 
 | ||||
|                                 const result = []; | ||||
|                                 let i = 0, j = 0; | ||||
| 
 | ||||
|                                 while (i < lines1.length || j < lines2.length) { | ||||
|                                 	console.log(`lines1[${i}]='${lines1[i]}', lines2[${j}]='${lines2[j]}'`); | ||||
|                                 	console.log(`i=${i}, j=${j}`); | ||||
|                                     if (lines1[i] === lines2[j]) { | ||||
|                                         result.push([i, j, lines1[i]]); | ||||
|                                         i++; | ||||
|                                         j++; | ||||
|                                         console.log(`i=${i}, j=${j}`); | ||||
| 
 | ||||
|                                     } else { | ||||
|                                         let k = i, l = j; | ||||
|                                         while (k < lines1.length && l < lines2.length && lines1[k] !== lines2[l]) { | ||||
|                                             k++; | ||||
|                                             l++; | ||||
|                                         } | ||||
| 
 | ||||
|                                         for (let x = i; x < k; x++) { | ||||
|                                             result.push([x, -1, lines1[x]]); | ||||
|                                         } | ||||
| 
 | ||||
|                                         for (let y = j; y < l; y++) { | ||||
|                                             result.push([-1, y, lines2[y]]); | ||||
|                                         } | ||||
| 
 | ||||
|                                         i = k; | ||||
|                                         j = l; | ||||
|                                     } | ||||
|                                 } | ||||
| 
 | ||||
|                                 return result; | ||||
|                             }; | ||||
| 
 | ||||
|                             const differences = diff(text1, text2); | ||||
|                             const highlightDifferences = async (pdf, differences) => { | ||||
|                                 for (const difference of differences) { | ||||
|                                     const [pageIndex, lineIndex, lineText] = difference; | ||||
|                                     if (lineIndex === -1) { | ||||
|                                         continue; | ||||
|                                     } | ||||
|                                     console.log(pageIndex); | ||||
|                                     const page = await pdf.getPage(pageIndex); | ||||
|                                     const viewport = page.getViewport({ scale: 1 }); | ||||
|                                     const [left,top] = viewport.convertToViewportPoint(0, lineIndex * 20); | ||||
|                                     const [right, bottom] = viewport.convertToViewportPoint(500, (lineIndex + 1) * 20); | ||||
|                                     const annotation = { | ||||
|                                             type: "Highlight", | ||||
|                                             rect: [left, top, right - left, bottom - top], | ||||
|                                             color: [255, 255, 0], | ||||
|                                             opacity: 0.5, | ||||
|                                             quadPoints: | ||||
|                                             [ | ||||
|                                                 left, top, right, top, right, bottom, left, bottom | ||||
|                                             ] | ||||
|                                         }; | ||||
|              | ||||
|                                         await page.addAnnotation(annotation); | ||||
|                                  | ||||
|                                         const message = `Difference found in page ${pageIndex }, line ${lineIndex + 1}: ${lineText}`; | ||||
|                                         const p = document.createElement("p"); | ||||
|                                         p.textContent = message; | ||||
|                                         document.getElementById("result").appendChild(p); | ||||
|                                     } | ||||
|                                 }; | ||||
|              | ||||
|                                 await highlightDifferences(pdf1, differences); | ||||
|                             } | ||||
|     </script> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|         <div th:insert="~{fragments/footer.html :: footer}"></div> | ||||
|     </div> | ||||
| </body> | ||||
| 
 | ||||
| </html> | ||||
| @ -3,20 +3,21 @@ | ||||
| 
 | ||||
| <head> | ||||
|     <th:block th:insert="~{fragments/common :: head(title=#{sign.title})}"></th:block> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <title>PDF Signature App</title> | ||||
|     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet"> | ||||
|     <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.12.313/pdf.min.js"></script> | ||||
|     <script src="https://unpkg.com/pdf-lib@1.18.0/dist/umd/pdf-lib.min.js"></script> | ||||
|     <script src="https://cdn.jsdelivr.net/npm/signature_pad@4.1.5/dist/signature_pad.umd.min.js"></script> | ||||
|     <script src="https://cdnjs.cloudflare.com/ajax/libs/interact.js/1.10.11/interact.min.js"></script> | ||||
|     <link rel="preconnect" href="https://fonts.googleapis.com"> | ||||
|     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||||
|     <link href="https://fonts.googleapis.com/css2?family=Estonia&family=Tangerine&family=Windsong&display=swap" rel="stylesheet"> | ||||
| </head> | ||||
|     <script src="js/signature_pad.umd.min.js"></script> | ||||
|     <script src="js/interact.min.js"></script> | ||||
| 
 | ||||
| </head> | ||||
| <style> | ||||
| @font-face { | ||||
|   font-family: 'Estonia'; | ||||
|   src: url(fonts/Estonia.woff2) format('woff2'); | ||||
| } | ||||
| @font-face { | ||||
|   font-family: 'Tangerine'; | ||||
|   src: url(fonts/Tangerine.woff2) format('woff2'); | ||||
| } | ||||
| </style> | ||||
| <body> | ||||
|     <th:block th:insert="~{fragments/common.html :: game}"></th:block> | ||||
|     <div id="page-container"> | ||||
|         <div id="content-wrap"> | ||||
|             <div th:insert="~{fragments/navbar.html :: navbar}"></div> | ||||
| @ -49,7 +50,7 @@ | ||||
|                         </script> | ||||
| 
 | ||||
|                         <div class="tab-group show-on-file-selected"> | ||||
|                             <div class="tab-container" title="Upload Image"> | ||||
|                             <div class="tab-container" th:title="#{sign.upload}"> | ||||
|                                 <div th:replace="~{fragments/common :: fileSelector(name='image-upload', multiple=true, accept='image/*', inputText=#{imgPrompt})}"></div> | ||||
|                                 <script> | ||||
|                                     const imageUpload = document.querySelector('input[name=image-upload]'); | ||||
| @ -67,11 +68,11 @@ | ||||
|                                     }); | ||||
|                                 </script> | ||||
|                             </div> | ||||
|                             <div class="tab-container drawing-pad-container" title="Draw Signature"> | ||||
|                             <div class="tab-container drawing-pad-container" th:title="#{sign.draw}"> | ||||
|                                 <canvas id="drawing-pad-canvas"></canvas> | ||||
|                                 <br> | ||||
|                                 <button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()">Clear</button> | ||||
|                                 <button id="save-signature" class="btn btn-outline-success mt-2" onclick="addDraggableFromPad()">Add</button> | ||||
|                                 <button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()" th:text="#{sign.clear}"></button> | ||||
|                                 <button id="save-signature" class="btn btn-outline-success mt-2" onclick="addDraggableFromPad()" th:text="#{sign.add}"></button> | ||||
|                                 <script> | ||||
|                                     const signaturePadCanvas = document.getElementById('drawing-pad-canvas'); | ||||
|                                     const signaturePad = new SignaturePad(signaturePadCanvas, { | ||||
| @ -160,17 +161,16 @@ | ||||
|                                     } | ||||
|                                 </style> | ||||
|                             </div> | ||||
|                             <div class="tab-container" title="Text Input"> | ||||
|                                 <label class="form-check-label" for="sigText">Text</label>  | ||||
|                             <div class="tab-container" th:title="#{sign.text}"> | ||||
|                                 <label class="form-check-label" for="sigText" th:text="#{text}"></label>  | ||||
|                                 <input type="text" class="form-control" id="sigText" name="sigText"> | ||||
|                                 <label>Font:</label>  | ||||
|                                 <label th:text="#{font}"></label>  | ||||
|                                 <select class="form-control" name="font" id="font-select"> | ||||
|                                     <option value="Estonia" class="estonia-font">Estonia</option> | ||||
|                                     <option value="Tangerine" class="tangerine-font">Tangerine</option> | ||||
|                                     <option value="Windsong" class="windsong-font">Windsong</option> | ||||
|                                 </select> | ||||
|                                 <div class="margin-auto-parent"> | ||||
|                                     <button id="save-text-signature" class="btn btn-outline-success mt-2 margin-center" onclick="addDraggableFromText()">Add</button> | ||||
|                                     <button id="save-text-signature" class="btn btn-outline-success mt-2 margin-center" onclick="addDraggableFromText()" th:text="#{sign.add}"></button> | ||||
|                                 </div> | ||||
|                                 <script> | ||||
|                                     function addDraggableFromText() { | ||||
| @ -213,7 +213,7 @@ | ||||
|                         <!-- draggables box --> | ||||
|                         <div id="box-drag-container" class="show-on-file-selected"> | ||||
|                             <canvas id="pdf-canvas"></canvas> | ||||
|                             <script src="/js/draggable-utils.js"></script> | ||||
|                             <script src="js/draggable-utils.js"></script> | ||||
|                             <div class="draggable-buttons-box ignore-rtl"> | ||||
|                                 <button class="btn btn-outline-secondary" onclick="DraggableUtils.deleteDraggableCanvas(DraggableUtils.getLastInteracted())"> | ||||
|                                     <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16"> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user