Compare commits
40 Commits
Frooodle/f
...
load-pdf-l
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fb605baa1 | ||
|
|
7e2a53a02e | ||
|
|
d389b5e2f3 | ||
|
|
de97492f39 | ||
|
|
9661e94092 | ||
|
|
2cfb553320 | ||
|
|
909a3347a0 | ||
|
|
de4144a1a4 | ||
|
|
bb1c859e0d | ||
|
|
b2862a3fc4 | ||
|
|
8788a7ee34 | ||
|
|
8c01425eee | ||
|
|
4d47e535b5 | ||
|
|
1fb78c3124 | ||
|
|
6a9dd4ea95 | ||
|
|
0773b8e11b | ||
|
|
184d89c44a | ||
|
|
df2e9bfc6e | ||
|
|
0045fe852b | ||
|
|
7d46d61d9e | ||
|
|
f8404ce9e9 | ||
|
|
7fad973a77 | ||
|
|
6410a99cf3 | ||
|
|
62e7c7e073 | ||
|
|
1d29a500b3 | ||
|
|
08b085c763 | ||
|
|
f256e8f029 | ||
|
|
0ad8c635ad | ||
|
|
12ff0ecac2 | ||
|
|
291bad4a2a | ||
|
|
c6ee96512a | ||
|
|
db563c765d | ||
|
|
6f52189ed2 | ||
|
|
580313151b | ||
|
|
765289c89e | ||
|
|
3d8686211d | ||
|
|
0a98e3bde3 | ||
|
|
78211d09c5 | ||
|
|
82219dd899 | ||
|
|
3c04486348 |
@@ -1,5 +1,5 @@
|
|||||||
# Main stage
|
# Main stage
|
||||||
FROM alpine:3.20.2
|
FROM alpine:3.20.3
|
||||||
|
|
||||||
# Copy necessary files
|
# Copy necessary files
|
||||||
COPY scripts /scripts
|
COPY scripts /scripts
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ RUN DOCKER_ENABLE_SECURITY=true \
|
|||||||
./gradlew clean build
|
./gradlew clean build
|
||||||
|
|
||||||
# Main stage
|
# Main stage
|
||||||
FROM alpine:3.20.2
|
FROM alpine:3.20.3
|
||||||
|
|
||||||
# Copy necessary files
|
# Copy necessary files
|
||||||
COPY scripts /scripts
|
COPY scripts /scripts
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# use alpine
|
# use alpine
|
||||||
FROM alpine:3.20.2
|
FROM alpine:3.20.3
|
||||||
|
|
||||||
ARG VERSION_TAG
|
ARG VERSION_TAG
|
||||||
|
|
||||||
|
|||||||
44
README.md
44
README.md
@@ -100,6 +100,8 @@ Demo of the app is available [here](https://stirlingpdf.io).
|
|||||||
- [PDF-LIB.js](https://github.com/Hopding/pdf-lib)
|
- [PDF-LIB.js](https://github.com/Hopding/pdf-lib)
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
### Windows
|
||||||
|
For windows users download the latest Stirling-PDF.exe from our [release](https://github.com/Stirling-Tools/Stirling-PDF/releases) section or by clicking [here](https://github.com/Stirling-Tools/Stirling-PDF/releases/latest/download/Stirling-PDF.exe)
|
||||||
|
|
||||||
### Locally
|
### Locally
|
||||||
|
|
||||||
@@ -170,39 +172,39 @@ Stirling PDF currently supports 38!
|
|||||||
|
|
||||||
| Language | Progress |
|
| Language | Progress |
|
||||||
| ------------------------------------------- | -------------------------------------- |
|
| ------------------------------------------- | -------------------------------------- |
|
||||||
| Arabic (العربية) (ar_AR) |  |
|
| Arabic (العربية) (ar_AR) |  |
|
||||||
| Basque (Euskara) (eu_ES) |  |
|
| Basque (Euskara) (eu_ES) |  |
|
||||||
| Bulgarian (Български) (bg_BG) |  |
|
| Bulgarian (Български) (bg_BG) |  |
|
||||||
| Catalan (Català) (ca_CA) |  |
|
| Catalan (Català) (ca_CA) |  |
|
||||||
| Croatian (Hrvatski) (hr_HR) |  |
|
| Croatian (Hrvatski) (hr_HR) |  |
|
||||||
| Czech (Česky) (cs_CZ) |  |
|
| Czech (Česky) (cs_CZ) |  |
|
||||||
| Danish (Dansk) (da_DK) |  |
|
| Danish (Dansk) (da_DK) |  |
|
||||||
| Dutch (Nederlands) (nl_NL) |  |
|
| Dutch (Nederlands) (nl_NL) |  |
|
||||||
| English (English) (en_GB) |  |
|
| English (English) (en_GB) |  |
|
||||||
| English (US) (en_US) |  |
|
| English (US) (en_US) |  |
|
||||||
| French (Français) (fr_FR) |  |
|
| French (Français) (fr_FR) |  |
|
||||||
| German (Deutsch) (de_DE) |  |
|
| German (Deutsch) (de_DE) |  |
|
||||||
| Greek (Ελληνικά) (el_GR) |  |
|
| Greek (Ελληνικά) (el_GR) |  |
|
||||||
| Hindi (हिंदी) (hi_IN) |  |
|
| Hindi (हिंदी) (hi_IN) |  |
|
||||||
| Hungarian (Magyar) (hu_HU) |  |
|
| Hungarian (Magyar) (hu_HU) |  |
|
||||||
| Indonesia (Bahasa Indonesia) (id_ID) |  |
|
| Indonesia (Bahasa Indonesia) (id_ID) |  |
|
||||||
| Irish (Gaeilge) (ga_IE) |  |
|
| Irish (Gaeilge) (ga_IE) |  |
|
||||||
| Italian (Italiano) (it_IT) |  |
|
| Italian (Italiano) (it_IT) |  |
|
||||||
| Japanese (日本語) (ja_JP) |  |
|
| Japanese (日本語) (ja_JP) |  |
|
||||||
| Korean (한국어) (ko_KR) |  |
|
| Korean (한국어) (ko_KR) |  |
|
||||||
| Norwegian (Norsk) (no_NB) |  |
|
| Norwegian (Norsk) (no_NB) |  |
|
||||||
| Polish (Polski) (pl_PL) |  |
|
| Polish (Polski) (pl_PL) |  |
|
||||||
| Portuguese (Português) (pt_PT) |  |
|
| Portuguese (Português) (pt_PT) |  |
|
||||||
| Portuguese Brazilian (Português) (pt_BR) |  |
|
| Portuguese Brazilian (Português) (pt_BR) |  |
|
||||||
| Romanian (Română) (ro_RO) |  |
|
| Romanian (Română) (ro_RO) |  |
|
||||||
| Russian (Русский) (ru_RU) |  |
|
| Russian (Русский) (ru_RU) |  |
|
||||||
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
||||||
| Simplified Chinese (简体中文) (zh_CN) |  |
|
| Simplified Chinese (简体中文) (zh_CN) |  |
|
||||||
| Slovakian (Slovensky) (sk_SK) |  |
|
| Slovakian (Slovensky) (sk_SK) |  |
|
||||||
| Spanish (Español) (es_ES) |  |
|
| Spanish (Español) (es_ES) |  |
|
||||||
| Swedish (Svenska) (sv_SE) |  |
|
| Swedish (Svenska) (sv_SE) |  |
|
||||||
| Thai (ไทย) (th_TH) |  |
|
| Thai (ไทย) (th_TH) |  |
|
||||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||||
| Turkish (Türkçe) (tr_TR) |  |
|
| Turkish (Türkçe) (tr_TR) |  |
|
||||||
| Ukrainian (Українська) (uk_UA) |  |
|
| Ukrainian (Українська) (uk_UA) |  |
|
||||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ ext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "stirling.software"
|
group = "stirling.software"
|
||||||
version = "0.28.3"
|
version = "0.29.0"
|
||||||
|
|
||||||
java {
|
java {
|
||||||
// 17 is lowest but we support and recommend 21
|
// 17 is lowest but we support and recommend 21
|
||||||
@@ -184,14 +184,14 @@ dependencies {
|
|||||||
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
|
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
|
||||||
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
|
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
|
||||||
implementation "io.micrometer:micrometer-core:1.13.3"
|
implementation "io.micrometer:micrometer-core:1.13.4"
|
||||||
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
|
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
|
||||||
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
||||||
implementation "org.commonmark:commonmark:0.22.0"
|
implementation "org.commonmark:commonmark:0.22.0"
|
||||||
implementation "org.commonmark:commonmark-ext-gfm-tables:0.22.0"
|
implementation "org.commonmark:commonmark-ext-gfm-tables:0.22.0"
|
||||||
// https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17
|
// https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17
|
||||||
implementation "com.bucket4j:bucket4j_jdk17-core:8.14.0"
|
implementation "com.bucket4j:bucket4j_jdk17-core:8.14.0"
|
||||||
implementation "com.fathzer:javaluator:3.0.4"
|
implementation "com.fathzer:javaluator:3.0.5"
|
||||||
|
|
||||||
developmentOnly("org.springframework.boot:spring-boot-devtools:$springBootVersion")
|
developmentOnly("org.springframework.boot:spring-boot-devtools:$springBootVersion")
|
||||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
appVersion: 0.28.3
|
appVersion: 0.29.0
|
||||||
description: locally hosted web application that allows you to perform various operations
|
description: locally hosted web application that allows you to perform various operations
|
||||||
on PDF files
|
on PDF files
|
||||||
home: https://github.com/Stirling-Tools/Stirling-PDF
|
home: https://github.com/Stirling-Tools/Stirling-PDF
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
version: '3.3'
|
|
||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Security-Fat
|
container_name: Stirling-PDF-Security-Fat
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
version: '3.3'
|
|
||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Security
|
container_name: Stirling-PDF-Security
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
version: '3.3'
|
|
||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Security
|
container_name: Stirling-PDF-Security
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
version: '3.3'
|
|
||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Ultra-Lite-Security
|
container_name: Stirling-PDF-Ultra-Lite-Security
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
version: '3.3'
|
|
||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Ultra-Lite
|
container_name: Stirling-PDF-Ultra-Lite
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
version: '3.3'
|
|
||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF
|
container_name: Stirling-PDF
|
||||||
|
|||||||
25
src/main/java/stirling/software/SPDF/EE/EEAppConfig.java
Normal file
25
src/main/java/stirling/software/SPDF/EE/EEAppConfig.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package stirling.software.SPDF.EE;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Lazy
|
||||||
|
public class EEAppConfig {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(EEAppConfig.class);
|
||||||
|
|
||||||
|
@Autowired ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
|
@Bean(name = "RunningEE")
|
||||||
|
public boolean runningEnterpriseEdition() {
|
||||||
|
// TODO: Implement EE detection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,6 @@ public class SPdfApplication {
|
|||||||
|
|
||||||
@Autowired private Environment env;
|
@Autowired private Environment env;
|
||||||
|
|
||||||
|
|
||||||
@Autowired ApplicationProperties applicationProperties;
|
@Autowired ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
private static String serverPortStatic;
|
private static String serverPortStatic;
|
||||||
|
|||||||
@@ -135,4 +135,29 @@ public class AppConfig {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(name = "termsAndConditions")
|
||||||
|
public String termsAndConditions() {
|
||||||
|
return applicationProperties.getLegal().getTermsAndConditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "privacyPolicy")
|
||||||
|
public String privacyPolicy() {
|
||||||
|
return applicationProperties.getLegal().getPrivacyPolicy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "cookiePolicy")
|
||||||
|
public String cookiePolicy() {
|
||||||
|
return applicationProperties.getLegal().getCookiePolicy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "impressum")
|
||||||
|
public String impressum() {
|
||||||
|
return applicationProperties.getLegal().getImpressum();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "accessibilityStatement")
|
||||||
|
public String accessibilityStatement() {
|
||||||
|
return applicationProperties.getLegal().getAccessibilityStatement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class AppUpdateService {
|
|||||||
@Bean(name = "shouldShow")
|
@Bean(name = "shouldShow")
|
||||||
@Scope("request")
|
@Scope("request")
|
||||||
public boolean shouldShow() {
|
public boolean shouldShow() {
|
||||||
boolean showUpdate = applicationProperties.getSystem().getShowUpdate();
|
boolean showUpdate = applicationProperties.getSystem().isShowUpdate();
|
||||||
boolean showAdminResult = (showAdmin != null) ? showAdmin.getShowUpdateOnlyAdmins() : true;
|
boolean showAdminResult = (showAdmin != null) ? showAdmin.getShowUpdateOnlyAdmins() : true;
|
||||||
return showUpdate && showAdminResult;
|
return showUpdate && showAdminResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import jakarta.servlet.FilterChain;
|
|||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import stirling.software.SPDF.utils.RequestUriUtils;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class MetricsFilter extends OncePerRequestFilter {
|
public class MetricsFilter extends OncePerRequestFilter {
|
||||||
@@ -30,32 +31,16 @@ public class MetricsFilter extends OncePerRequestFilter {
|
|||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
String uri = request.getRequestURI();
|
String uri = request.getRequestURI();
|
||||||
|
|
||||||
// System.out.println("uri="+uri + ", method=" + request.getMethod() );
|
if (RequestUriUtils.isTrackableResource(request.getContextPath(), uri)) {
|
||||||
// Ignore static resources
|
|
||||||
if (!(uri.startsWith("/js")
|
|
||||||
|| uri.startsWith("/v1/api-docs")
|
|
||||||
|| uri.endsWith("robots.txt")
|
|
||||||
|| uri.startsWith("/images")
|
|
||||||
|| uri.endsWith(".png")
|
|
||||||
|| uri.endsWith(".ico")
|
|
||||||
|| uri.endsWith(".css")
|
|
||||||
|| uri.endsWith(".map")
|
|
||||||
|| uri.endsWith(".svg")
|
|
||||||
|| uri.endsWith(".js")
|
|
||||||
|| uri.contains("swagger")
|
|
||||||
|| uri.startsWith("/api/v1/info")
|
|
||||||
|| uri.startsWith("/site.webmanifest")
|
|
||||||
|| uri.startsWith("/fonts")
|
|
||||||
|| uri.startsWith("/pdfjs"))) {
|
|
||||||
|
|
||||||
Counter counter =
|
Counter counter =
|
||||||
Counter.builder("http.requests")
|
Counter.builder("http.requests")
|
||||||
.tag("uri", uri)
|
.tag("session", request.getSession().getId())
|
||||||
.tag("method", request.getMethod())
|
.tag("method", request.getMethod())
|
||||||
|
.tag("uri", uri)
|
||||||
.register(meterRegistry);
|
.register(meterRegistry);
|
||||||
|
|
||||||
counter.increment();
|
counter.increment();
|
||||||
// System.out.println("Counted");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
package stirling.software.SPDF.config;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
import stirling.software.SPDF.model.PdfMetadata;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PdfMetadataService {
|
||||||
|
|
||||||
|
private final ApplicationProperties applicationProperties;
|
||||||
|
private final String appVersion;
|
||||||
|
private final UserServiceInterface userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public PdfMetadataService(
|
||||||
|
ApplicationProperties applicationProperties,
|
||||||
|
@Qualifier("appVersion") String appVersion,
|
||||||
|
@Autowired(required = false) UserServiceInterface userService) {
|
||||||
|
this.applicationProperties = applicationProperties;
|
||||||
|
this.appVersion = appVersion;
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PdfMetadata extractMetadataFromPdf(PDDocument pdf) {
|
||||||
|
return PdfMetadata.builder()
|
||||||
|
.author(pdf.getDocumentInformation().getAuthor())
|
||||||
|
.producer(pdf.getDocumentInformation().getProducer())
|
||||||
|
.title(pdf.getDocumentInformation().getTitle())
|
||||||
|
.creator(pdf.getDocumentInformation().getCreator())
|
||||||
|
.subject(pdf.getDocumentInformation().getSubject())
|
||||||
|
.keywords(pdf.getDocumentInformation().getKeywords())
|
||||||
|
.creationDate(pdf.getDocumentInformation().getCreationDate())
|
||||||
|
.modificationDate(pdf.getDocumentInformation().getModificationDate())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultMetadata(PDDocument pdf) {
|
||||||
|
PdfMetadata metadata = extractMetadataFromPdf(pdf);
|
||||||
|
setMetadataToPdf(pdf, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetadataToPdf(PDDocument pdf, PdfMetadata pdfMetadata) {
|
||||||
|
setMetadataToPdf(pdf, pdfMetadata, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetadataToPdf(PDDocument pdf, PdfMetadata pdfMetadata, boolean newlyCreated) {
|
||||||
|
if (newlyCreated || pdfMetadata.getCreationDate() == null) {
|
||||||
|
setNewDocumentMetadata(pdf, pdfMetadata);
|
||||||
|
}
|
||||||
|
setCommonMetadata(pdf, pdfMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setNewDocumentMetadata(PDDocument pdf, PdfMetadata pdfMetadata) {
|
||||||
|
|
||||||
|
String creator = "Stirling-PDF";
|
||||||
|
|
||||||
|
// if (applicationProperties
|
||||||
|
// .getEnterpriseEdition()
|
||||||
|
// .getCustomMetadata()
|
||||||
|
// .isAutoUpdateMetadata()) {
|
||||||
|
|
||||||
|
// producer =
|
||||||
|
//
|
||||||
|
// applicationProperties.getEnterpriseEdition().getCustomMetadata().getProducer();
|
||||||
|
// creator =
|
||||||
|
// applicationProperties.getEnterpriseEdition().getCustomMetadata().getCreator();
|
||||||
|
// title = applicationProperties.getEnterpriseEdition().getCustomMetadata().getTitle();
|
||||||
|
|
||||||
|
// if ("{filename}".equals(title)) {
|
||||||
|
// title = "Filename"; // Replace with actual filename logic
|
||||||
|
// } else if ("{unchanged}".equals(title)) {
|
||||||
|
// title = pdfMetadata.getTitle(); // Keep the original title
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
pdf.getDocumentInformation().setCreator(creator + " " + appVersion);
|
||||||
|
pdf.getDocumentInformation().setCreationDate(Calendar.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCommonMetadata(PDDocument pdf, PdfMetadata pdfMetadata) {
|
||||||
|
String producer = "Stirling-PDF";
|
||||||
|
String title = pdfMetadata.getTitle();
|
||||||
|
pdf.getDocumentInformation().setTitle(title);
|
||||||
|
pdf.getDocumentInformation().setProducer(producer + " " + appVersion);
|
||||||
|
pdf.getDocumentInformation().setSubject(pdfMetadata.getSubject());
|
||||||
|
pdf.getDocumentInformation().setKeywords(pdfMetadata.getKeywords());
|
||||||
|
pdf.getDocumentInformation().setModificationDate(Calendar.getInstance());
|
||||||
|
|
||||||
|
String author = pdfMetadata.getAuthor();
|
||||||
|
// if (applicationProperties
|
||||||
|
// .getEnterpriseEdition()
|
||||||
|
// .getCustomMetadata()
|
||||||
|
// .isAutoUpdateMetadata()) {
|
||||||
|
// author = applicationProperties.getEnterpriseEdition().getCustomMetadata().getAuthor();
|
||||||
|
|
||||||
|
// if (userService != null) {
|
||||||
|
// author = author.replace("username", userService.getCurrentUsername());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
pdf.getDocumentInformation().setAuthor(author);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ class AppUpdateAuthService implements ShowAdminInterface {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getShowUpdateOnlyAdmins() {
|
public boolean getShowUpdateOnlyAdmins() {
|
||||||
boolean showUpdate = applicationProperties.getSystem().getShowUpdate();
|
boolean showUpdate = applicationProperties.getSystem().isShowUpdate();
|
||||||
if (!showUpdate) {
|
if (!showUpdate) {
|
||||||
return showUpdate;
|
return showUpdate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,8 +152,8 @@ public class SecurityConfiguration {
|
|||||||
.authenticated());
|
.authenticated());
|
||||||
|
|
||||||
// Handle OAUTH2 Logins
|
// Handle OAUTH2 Logins
|
||||||
if (applicationProperties.getSecurity().getOAUTH2() != null
|
if (applicationProperties.getSecurity().getOauth2() != null
|
||||||
&& applicationProperties.getSecurity().getOAUTH2().getEnabled()
|
&& applicationProperties.getSecurity().getOauth2().getEnabled()
|
||||||
&& !applicationProperties
|
&& !applicationProperties
|
||||||
.getSecurity()
|
.getSecurity()
|
||||||
.getLoginMethod()
|
.getLoginMethod()
|
||||||
@@ -222,7 +222,7 @@ public class SecurityConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientRegistration> googleClientRegistration() {
|
private Optional<ClientRegistration> googleClientRegistration() {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
if (oauth == null || !oauth.getEnabled()) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@@ -251,7 +251,7 @@ public class SecurityConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientRegistration> keycloakClientRegistration() {
|
private Optional<ClientRegistration> keycloakClientRegistration() {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
if (oauth == null || !oauth.getEnabled()) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@@ -275,7 +275,7 @@ public class SecurityConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientRegistration> githubClientRegistration() {
|
private Optional<ClientRegistration> githubClientRegistration() {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
if (oauth == null || !oauth.getEnabled()) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@@ -304,7 +304,7 @@ public class SecurityConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientRegistration> oidcClientRegistration() {
|
private Optional<ClientRegistration> oidcClientRegistration() {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
if (oauth == null
|
if (oauth == null
|
||||||
|| oauth.getIssuer() == null
|
|| oauth.getIssuer() == null
|
||||||
|| oauth.getIssuer().isEmpty()
|
|| oauth.getIssuer().isEmpty()
|
||||||
@@ -352,7 +352,7 @@ public class SecurityConfiguration {
|
|||||||
String useAsUsername =
|
String useAsUsername =
|
||||||
applicationProperties
|
applicationProperties
|
||||||
.getSecurity()
|
.getSecurity()
|
||||||
.getOAUTH2()
|
.getOauth2()
|
||||||
.getUseAsUsername();
|
.getUseAsUsername();
|
||||||
Optional<User> userOpt =
|
Optional<User> userOpt =
|
||||||
userService.findByUsernameIgnoreCase(
|
userService.findByUsernameIgnoreCase(
|
||||||
|
|||||||
@@ -159,7 +159,10 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (String pattern : permitAllPatterns) {
|
for (String pattern : permitAllPatterns) {
|
||||||
if (uri.startsWith(pattern) || uri.endsWith(".svg")) {
|
if (uri.startsWith(pattern)
|
||||||
|
|| uri.endsWith(".svg")
|
||||||
|
|| uri.endsWith(".png")
|
||||||
|
|| uri.endsWith(".ico")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
|
|||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.core.session.SessionInformation;
|
import org.springframework.security.core.session.SessionInformation;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
@@ -342,4 +343,14 @@ public class UserService implements UserServiceInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCurrentUsername() {
|
||||||
|
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
|
|
||||||
|
if (principal instanceof UserDetails) {
|
||||||
|
return ((UserDetails) principal).getUsername();
|
||||||
|
} else {
|
||||||
|
return principal.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class CustomOAuth2AuthenticationSuccessHandler
|
|||||||
// Redirect to the original destination
|
// Redirect to the original destination
|
||||||
super.onAuthenticationSuccess(request, response, authentication);
|
super.onAuthenticationSuccess(request, response, authentication);
|
||||||
} else {
|
} else {
|
||||||
OAUTH2 oAuth = applicationProperties.getSecurity().getOAUTH2();
|
OAUTH2 oAuth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
if (loginAttemptService.isBlocked(username)) {
|
if (loginAttemptService.isBlocked(username)) {
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHand
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
if (authentication instanceof OAuth2AuthenticationToken) {
|
if (authentication instanceof OAuth2AuthenticationToken) {
|
||||||
OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;
|
OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class CustomOAuth2UserService implements OAuth2UserService<OidcUserReques
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
|
public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
|
||||||
OAUTH2 oauth2 = applicationProperties.getSecurity().getOAUTH2();
|
OAUTH2 oauth2 = applicationProperties.getSecurity().getOauth2();
|
||||||
String usernameAttribute = oauth2.getUseAsUsername();
|
String usernameAttribute = oauth2.getUseAsUsername();
|
||||||
if (usernameAttribute == null || usernameAttribute.trim().isEmpty()) {
|
if (usernameAttribute == null || usernameAttribute.trim().isEmpty()) {
|
||||||
Client client = oauth2.getClient();
|
Client client = oauth2.getClient();
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -23,6 +24,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.CropPdfForm;
|
import stirling.software.SPDF.model.api.general.CropPdfForm;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -32,6 +34,13 @@ public class CropController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(CropController.class);
|
private static final Logger logger = LoggerFactory.getLogger(CropController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CropController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/crop", consumes = "multipart/form-data")
|
@PostMapping(value = "/crop", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Crops a PDF document",
|
summary = "Crops a PDF document",
|
||||||
@@ -40,7 +49,8 @@ public class CropController {
|
|||||||
public ResponseEntity<byte[]> cropPdf(@ModelAttribute CropPdfForm form) throws IOException {
|
public ResponseEntity<byte[]> cropPdf(@ModelAttribute CropPdfForm form) throws IOException {
|
||||||
PDDocument sourceDocument = Loader.loadPDF(form.getFileInput().getBytes());
|
PDDocument sourceDocument = Loader.loadPDF(form.getFileInput().getBytes());
|
||||||
|
|
||||||
PDDocument newDocument = new PDDocument();
|
PDDocument newDocument =
|
||||||
|
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||||
|
|
||||||
int totalPages = sourceDocument.getNumberOfPages();
|
int totalPages = sourceDocument.getNumberOfPages();
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -33,6 +34,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.MergePdfsRequest;
|
import stirling.software.SPDF.model.api.general.MergePdfsRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -43,9 +45,16 @@ public class MergeController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(MergeController.class);
|
private static final Logger logger = LoggerFactory.getLogger(MergeController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public MergeController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
// Merges a list of PDDocument objects into a single PDDocument
|
// Merges a list of PDDocument objects into a single PDDocument
|
||||||
public PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
|
public PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
|
||||||
PDDocument mergedDoc = new PDDocument();
|
PDDocument mergedDoc = pdfDocumentFactory.createNewDocument();
|
||||||
for (PDDocument doc : documents) {
|
for (PDDocument doc : documents) {
|
||||||
for (PDPage page : doc.getPages()) {
|
for (PDPage page : doc.getPages()) {
|
||||||
mergedDoc.addPage(page);
|
mergedDoc.addPage(page);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -26,6 +27,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest;
|
import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -35,6 +37,13 @@ public class MultiPageLayoutController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(MultiPageLayoutController.class);
|
private static final Logger logger = LoggerFactory.getLogger(MultiPageLayoutController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public MultiPageLayoutController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/multi-page-layout", consumes = "multipart/form-data")
|
@PostMapping(value = "/multi-page-layout", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Merge multiple pages of a PDF document into a single page",
|
summary = "Merge multiple pages of a PDF document into a single page",
|
||||||
@@ -60,7 +69,8 @@ public class MultiPageLayoutController {
|
|||||||
int rows = pagesPerSheet == 2 || pagesPerSheet == 3 ? 1 : (int) Math.sqrt(pagesPerSheet);
|
int rows = pagesPerSheet == 2 || pagesPerSheet == 3 ? 1 : (int) Math.sqrt(pagesPerSheet);
|
||||||
|
|
||||||
PDDocument sourceDocument = Loader.loadPDF(file.getBytes());
|
PDDocument sourceDocument = Loader.loadPDF(file.getBytes());
|
||||||
PDDocument newDocument = new PDDocument();
|
PDDocument newDocument =
|
||||||
|
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||||
PDPage newPage = new PDPage(PDRectangle.A4);
|
PDPage newPage = new PDPage(PDRectangle.A4);
|
||||||
newDocument.addPage(newPage);
|
newDocument.addPage(newPage);
|
||||||
|
|
||||||
|
|||||||
@@ -3,16 +3,15 @@ package stirling.software.SPDF.controller.api;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFFile;
|
import stirling.software.SPDF.model.api.PDFFile;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.service.PdfImageRemovalService;
|
import stirling.software.SPDF.service.PdfImageRemovalService;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -25,15 +24,21 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
public class PdfImageRemovalController {
|
public class PdfImageRemovalController {
|
||||||
|
|
||||||
// Service for removing images from PDFs
|
// Service for removing images from PDFs
|
||||||
@Autowired private PdfImageRemovalService pdfImageRemovalService;
|
private final PdfImageRemovalService pdfImageRemovalService;
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for dependency injection of PdfImageRemovalService.
|
* Constructor for dependency injection of PdfImageRemovalService.
|
||||||
*
|
*
|
||||||
* @param pdfImageRemovalService The service used for removing images from PDFs.
|
* @param pdfImageRemovalService The service used for removing images from PDFs.
|
||||||
*/
|
*/
|
||||||
public PdfImageRemovalController(PdfImageRemovalService pdfImageRemovalService) {
|
@Autowired
|
||||||
|
public PdfImageRemovalController(
|
||||||
|
PdfImageRemovalService pdfImageRemovalService,
|
||||||
|
CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
this.pdfImageRemovalService = pdfImageRemovalService;
|
this.pdfImageRemovalService = pdfImageRemovalService;
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,14 +58,8 @@ public class PdfImageRemovalController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint remove images from file to reduce the file size.Input:PDF Output:PDF Type:MISO")
|
"This endpoint remove images from file to reduce the file size.Input:PDF Output:PDF Type:MISO")
|
||||||
public ResponseEntity<byte[]> removeImages(@ModelAttribute PDFFile file) throws IOException {
|
public ResponseEntity<byte[]> removeImages(@ModelAttribute PDFFile file) throws IOException {
|
||||||
|
// Load the PDF document
|
||||||
MultipartFile pdf = file.getFileInput();
|
PDDocument document = pdfDocumentFactory.load(file);
|
||||||
|
|
||||||
// Convert the MultipartFile to a byte array
|
|
||||||
byte[] pdfBytes = pdf.getBytes();
|
|
||||||
|
|
||||||
// Load the PDF document from the byte array
|
|
||||||
PDDocument document = Loader.loadPDF(pdfBytes);
|
|
||||||
|
|
||||||
// Remove images from the PDF document using the service
|
// Remove images from the PDF document using the service
|
||||||
PDDocument modifiedDocument = pdfImageRemovalService.removeImagesFromPdf(document);
|
PDDocument modifiedDocument = pdfImageRemovalService.removeImagesFromPdf(document);
|
||||||
@@ -74,7 +73,8 @@ public class PdfImageRemovalController {
|
|||||||
|
|
||||||
// Generate a new filename for the modified PDF
|
// Generate a new filename for the modified PDF
|
||||||
String mergedFileName =
|
String mergedFileName =
|
||||||
pdf.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_removed_images.pdf";
|
file.getFileInput().getOriginalFilename().replaceFirst("[.][^.]+$", "")
|
||||||
|
+ "_removed_images.pdf";
|
||||||
|
|
||||||
// Convert the byte array to a web response and return it
|
// Convert the byte array to a web response and return it
|
||||||
return WebResponseUtils.bytesToWebResponse(outputStream.toByteArray(), mergedFileName);
|
return WebResponseUtils.bytesToWebResponse(outputStream.toByteArray(), mergedFileName);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.util.Map;
|
|||||||
import org.apache.pdfbox.Loader;
|
import org.apache.pdfbox.Loader;
|
||||||
import org.apache.pdfbox.multipdf.Overlay;
|
import org.apache.pdfbox.multipdf.Overlay;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -25,6 +26,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.OverlayPdfsRequest;
|
import stirling.software.SPDF.model.api.general.OverlayPdfsRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -33,6 +35,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
@Tag(name = "General", description = "General APIs")
|
@Tag(name = "General", description = "General APIs")
|
||||||
public class PdfOverlayController {
|
public class PdfOverlayController {
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public PdfOverlayController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data")
|
@PostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Overlay PDF files in various modes",
|
summary = "Overlay PDF files in various modes",
|
||||||
@@ -56,7 +65,7 @@ public class PdfOverlayController {
|
|||||||
// "FixedRepeatOverlay"
|
// "FixedRepeatOverlay"
|
||||||
int[] counts = request.getCounts(); // Used for FixedRepeatOverlay mode
|
int[] counts = request.getCounts(); // Used for FixedRepeatOverlay mode
|
||||||
|
|
||||||
try (PDDocument basePdf = Loader.loadPDF(baseFile.getBytes());
|
try (PDDocument basePdf = pdfDocumentFactory.load(baseFile);
|
||||||
Overlay overlay = new Overlay()) {
|
Overlay overlay = new Overlay()) {
|
||||||
Map<Integer, String> overlayGuide =
|
Map<Integer, String> overlayGuide =
|
||||||
prepareOverlayGuide(
|
prepareOverlayGuide(
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -24,6 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
import stirling.software.SPDF.model.SortTypes;
|
import stirling.software.SPDF.model.SortTypes;
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
import stirling.software.SPDF.model.api.general.RearrangePagesRequest;
|
import stirling.software.SPDF.model.api.general.RearrangePagesRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -34,6 +36,13 @@ public class RearrangePagesPDFController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RearrangePagesPDFController.class);
|
private static final Logger logger = LoggerFactory.getLogger(RearrangePagesPDFController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RearrangePagesPDFController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/remove-pages")
|
@PostMapping(consumes = "multipart/form-data", value = "/remove-pages")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Remove pages from a PDF file",
|
summary = "Remove pages from a PDF file",
|
||||||
@@ -45,7 +54,7 @@ public class RearrangePagesPDFController {
|
|||||||
MultipartFile pdfFile = request.getFileInput();
|
MultipartFile pdfFile = request.getFileInput();
|
||||||
String pagesToDelete = request.getPageNumbers();
|
String pagesToDelete = request.getPageNumbers();
|
||||||
|
|
||||||
PDDocument document = Loader.loadPDF(pdfFile.getBytes());
|
PDDocument document = pdfDocumentFactory.load(pdfFile);
|
||||||
|
|
||||||
// Split the page order string into an array of page numbers or range of numbers
|
// Split the page order string into an array of page numbers or range of numbers
|
||||||
String[] pageOrderArr = pagesToDelete.split(",");
|
String[] pageOrderArr = pagesToDelete.split(",");
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package stirling.software.SPDF.controller.api;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -20,6 +20,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.RotatePDFRequest;
|
import stirling.software.SPDF.model.api.general.RotatePDFRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -29,6 +30,13 @@ public class RotationController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RotationController.class);
|
private static final Logger logger = LoggerFactory.getLogger(RotationController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RotationController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/rotate-pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/rotate-pdf")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Rotate a PDF file",
|
summary = "Rotate a PDF file",
|
||||||
@@ -39,7 +47,7 @@ public class RotationController {
|
|||||||
MultipartFile pdfFile = request.getFileInput();
|
MultipartFile pdfFile = request.getFileInput();
|
||||||
Integer angle = request.getAngle();
|
Integer angle = request.getAngle();
|
||||||
// Load the PDF document
|
// Load the PDF document
|
||||||
PDDocument document = Loader.loadPDF(pdfFile.getBytes());
|
PDDocument document = pdfDocumentFactory.load(request);
|
||||||
|
|
||||||
// Get the list of pages in the document
|
// Get the list of pages in the document
|
||||||
PDPageTree pages = document.getPages();
|
PDPageTree pages = document.getPages();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -27,6 +28,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.ScalePagesRequest;
|
import stirling.software.SPDF.model.api.general.ScalePagesRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -36,6 +38,13 @@ public class ScalePagesController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ScalePagesController.class);
|
private static final Logger logger = LoggerFactory.getLogger(ScalePagesController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ScalePagesController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/scale-pages", consumes = "multipart/form-data")
|
@PostMapping(value = "/scale-pages", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Change the size of a PDF page/document",
|
summary = "Change the size of a PDF page/document",
|
||||||
@@ -47,29 +56,11 @@ public class ScalePagesController {
|
|||||||
String targetPDRectangle = request.getPageSize();
|
String targetPDRectangle = request.getPageSize();
|
||||||
float scaleFactor = request.getScaleFactor();
|
float scaleFactor = request.getScaleFactor();
|
||||||
|
|
||||||
Map<String, PDRectangle> sizeMap = new HashMap<>();
|
|
||||||
// Add A0 - A10
|
|
||||||
sizeMap.put("A0", PDRectangle.A0);
|
|
||||||
sizeMap.put("A1", PDRectangle.A1);
|
|
||||||
sizeMap.put("A2", PDRectangle.A2);
|
|
||||||
sizeMap.put("A3", PDRectangle.A3);
|
|
||||||
sizeMap.put("A4", PDRectangle.A4);
|
|
||||||
sizeMap.put("A5", PDRectangle.A5);
|
|
||||||
sizeMap.put("A6", PDRectangle.A6);
|
|
||||||
|
|
||||||
// Add other sizes
|
|
||||||
sizeMap.put("LETTER", PDRectangle.LETTER);
|
|
||||||
sizeMap.put("LEGAL", PDRectangle.LEGAL);
|
|
||||||
|
|
||||||
if (!sizeMap.containsKey(targetPDRectangle)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Invalid PDRectangle. It must be one of the following: A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10");
|
|
||||||
}
|
|
||||||
|
|
||||||
PDRectangle targetSize = sizeMap.get(targetPDRectangle);
|
|
||||||
|
|
||||||
PDDocument sourceDocument = Loader.loadPDF(file.getBytes());
|
PDDocument sourceDocument = Loader.loadPDF(file.getBytes());
|
||||||
PDDocument outputDocument = new PDDocument();
|
PDDocument outputDocument =
|
||||||
|
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||||
|
|
||||||
|
PDRectangle targetSize = getTargetSize(targetPDRectangle, sourceDocument);
|
||||||
|
|
||||||
int totalPages = sourceDocument.getNumberOfPages();
|
int totalPages = sourceDocument.getNumberOfPages();
|
||||||
for (int i = 0; i < totalPages; i++) {
|
for (int i = 0; i < totalPages; i++) {
|
||||||
@@ -116,4 +107,45 @@ public class ScalePagesController {
|
|||||||
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||||
+ "_scaled.pdf");
|
+ "_scaled.pdf");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PDRectangle getTargetSize(String targetPDRectangle, PDDocument sourceDocument) {
|
||||||
|
if (targetPDRectangle.equals("KEEP")) {
|
||||||
|
if (sourceDocument.getNumberOfPages() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use the first page to determine the target page size
|
||||||
|
PDPage sourcePage = sourceDocument.getPage(0);
|
||||||
|
PDRectangle sourceSize = sourcePage.getMediaBox();
|
||||||
|
|
||||||
|
return sourceSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, PDRectangle> sizeMap = getSizeMap();
|
||||||
|
|
||||||
|
if (sizeMap.containsKey(targetPDRectangle)) {
|
||||||
|
return sizeMap.get(targetPDRectangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Invalid PDRectangle. It must be one of the following: A0, A1, A2, A3, A4, A5, A6, LETTER, LEGAL, KEEP");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, PDRectangle> getSizeMap() {
|
||||||
|
Map<String, PDRectangle> sizeMap = new HashMap<>();
|
||||||
|
// Add A0 - A6
|
||||||
|
sizeMap.put("A0", PDRectangle.A0);
|
||||||
|
sizeMap.put("A1", PDRectangle.A1);
|
||||||
|
sizeMap.put("A2", PDRectangle.A2);
|
||||||
|
sizeMap.put("A3", PDRectangle.A3);
|
||||||
|
sizeMap.put("A4", PDRectangle.A4);
|
||||||
|
sizeMap.put("A5", PDRectangle.A5);
|
||||||
|
sizeMap.put("A6", PDRectangle.A6);
|
||||||
|
|
||||||
|
// Add other sizes
|
||||||
|
sizeMap.put("LETTER", PDRectangle.LETTER);
|
||||||
|
sizeMap.put("LEGAL", PDRectangle.LEGAL);
|
||||||
|
|
||||||
|
return sizeMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -27,9 +28,8 @@ import io.github.pixee.security.Filenames;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.PdfMetadata;
|
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -38,6 +38,12 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
public class SplitPDFController {
|
public class SplitPDFController {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SplitPDFController.class);
|
private static final Logger logger = LoggerFactory.getLogger(SplitPDFController.class);
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SplitPDFController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/split-pages")
|
@PostMapping(consumes = "multipart/form-data", value = "/split-pages")
|
||||||
@Operation(
|
@Operation(
|
||||||
@@ -51,7 +57,7 @@ public class SplitPDFController {
|
|||||||
// open the pdf document
|
// open the pdf document
|
||||||
|
|
||||||
PDDocument document = Loader.loadPDF(file.getBytes());
|
PDDocument document = Loader.loadPDF(file.getBytes());
|
||||||
PdfMetadata metadata = PdfUtils.extractMetadataFromPdf(document);
|
// PdfMetadata metadata = PdfMetadataService.extractMetadataFromPdf(document);
|
||||||
int totalPages = document.getNumberOfPages();
|
int totalPages = document.getNumberOfPages();
|
||||||
List<Integer> pageNumbers = request.getPageNumbersList(document, false);
|
List<Integer> pageNumbers = request.getPageNumbersList(document, false);
|
||||||
System.out.println(
|
System.out.println(
|
||||||
@@ -70,7 +76,8 @@ public class SplitPDFController {
|
|||||||
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
|
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
|
||||||
int previousPageNumber = 0;
|
int previousPageNumber = 0;
|
||||||
for (int splitPoint : pageNumbers) {
|
for (int splitPoint : pageNumbers) {
|
||||||
try (PDDocument splitDocument = new PDDocument()) {
|
try (PDDocument splitDocument =
|
||||||
|
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(document)) {
|
||||||
for (int i = previousPageNumber; i <= splitPoint; i++) {
|
for (int i = previousPageNumber; i <= splitPoint; i++) {
|
||||||
PDPage page = document.getPage(i);
|
PDPage page = document.getPage(i);
|
||||||
splitDocument.addPage(page);
|
splitDocument.addPage(page);
|
||||||
@@ -79,7 +86,7 @@ public class SplitPDFController {
|
|||||||
previousPageNumber = splitPoint + 1;
|
previousPageNumber = splitPoint + 1;
|
||||||
|
|
||||||
// Transfer metadata to split pdf
|
// Transfer metadata to split pdf
|
||||||
PdfUtils.setMetadataToPdf(splitDocument, metadata);
|
// PdfMetadataService.setMetadataToPdf(splitDocument, metadata);
|
||||||
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
splitDocument.save(baos);
|
splitDocument.save(baos);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocume
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
|
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -31,9 +32,9 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import stirling.software.SPDF.config.PdfMetadataService;
|
||||||
import stirling.software.SPDF.model.PdfMetadata;
|
import stirling.software.SPDF.model.PdfMetadata;
|
||||||
import stirling.software.SPDF.model.api.SplitPdfByChaptersRequest;
|
import stirling.software.SPDF.model.api.SplitPdfByChaptersRequest;
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -44,6 +45,13 @@ public class SplitPdfByChaptersController {
|
|||||||
private static final Logger logger =
|
private static final Logger logger =
|
||||||
LoggerFactory.getLogger(SplitPdfByChaptersController.class);
|
LoggerFactory.getLogger(SplitPdfByChaptersController.class);
|
||||||
|
|
||||||
|
private final PdfMetadataService pdfMetadataService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SplitPdfByChaptersController(PdfMetadataService pdfMetadataService) {
|
||||||
|
this.pdfMetadataService = pdfMetadataService;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/split-pdf-by-chapters", consumes = "multipart/form-data")
|
@PostMapping(value = "/split-pdf-by-chapters", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Split PDFs by Chapters",
|
summary = "Split PDFs by Chapters",
|
||||||
@@ -258,7 +266,7 @@ public class SplitPdfByChaptersController {
|
|||||||
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
|
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
|
||||||
PdfMetadata metadata = null;
|
PdfMetadata metadata = null;
|
||||||
if (includeMetadata) {
|
if (includeMetadata) {
|
||||||
metadata = PdfUtils.extractMetadataFromPdf(sourceDocument);
|
metadata = pdfMetadataService.extractMetadataFromPdf(sourceDocument);
|
||||||
}
|
}
|
||||||
for (Bookmark bookmark : bookmarks) {
|
for (Bookmark bookmark : bookmarks) {
|
||||||
try (PDDocument splitDocument = new PDDocument()) {
|
try (PDDocument splitDocument = new PDDocument()) {
|
||||||
@@ -273,7 +281,7 @@ public class SplitPdfByChaptersController {
|
|||||||
}
|
}
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
if (includeMetadata) {
|
if (includeMetadata) {
|
||||||
PdfUtils.setMetadataToPdf(splitDocument, metadata);
|
pdfMetadataService.setMetadataToPdf(splitDocument, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
splitDocument.save(baos);
|
splitDocument.save(baos);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -33,6 +34,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.SplitPdfBySectionsRequest;
|
import stirling.software.SPDF.model.api.SplitPdfBySectionsRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -43,6 +45,13 @@ public class SplitPdfBySectionsController {
|
|||||||
private static final Logger logger =
|
private static final Logger logger =
|
||||||
LoggerFactory.getLogger(SplitPdfBySectionsController.class);
|
LoggerFactory.getLogger(SplitPdfBySectionsController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SplitPdfBySectionsController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data")
|
@PostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Split PDF pages into smaller sections",
|
summary = "Split PDF pages into smaller sections",
|
||||||
@@ -65,7 +74,7 @@ public class SplitPdfBySectionsController {
|
|||||||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||||
.replaceFirst("[.][^.]+$", "");
|
.replaceFirst("[.][^.]+$", "");
|
||||||
if (merge) {
|
if (merge) {
|
||||||
MergeController mergeController = new MergeController();
|
MergeController mergeController = new MergeController(pdfDocumentFactory);
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
mergeController.mergeDocuments(splitDocuments).save(baos);
|
mergeController.mergeDocuments(splitDocuments).save(baos);
|
||||||
return WebResponseUtils.bytesToWebResponse(baos.toByteArray(), filename + "_split.pdf");
|
return WebResponseUtils.bytesToWebResponse(baos.toByteArray(), filename + "_split.pdf");
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -25,6 +26,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.SplitPdfBySizeOrCountRequest;
|
import stirling.software.SPDF.model.api.general.SplitPdfBySizeOrCountRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -34,6 +36,12 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
public class SplitPdfBySizeController {
|
public class SplitPdfBySizeController {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SplitPdfBySizeController.class);
|
private static final Logger logger = LoggerFactory.getLogger(SplitPdfBySizeController.class);
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SplitPdfBySizeController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data")
|
@PostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
@@ -84,7 +92,8 @@ public class SplitPdfBySizeController {
|
|||||||
PDDocument sourceDocument, long maxBytes, ZipOutputStream zipOut, String baseFilename)
|
PDDocument sourceDocument, long maxBytes, ZipOutputStream zipOut, String baseFilename)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
long currentSize = 0;
|
long currentSize = 0;
|
||||||
PDDocument currentDoc = new PDDocument();
|
PDDocument currentDoc =
|
||||||
|
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||||
int fileIndex = 1;
|
int fileIndex = 1;
|
||||||
|
|
||||||
for (int pageIndex = 0; pageIndex < sourceDocument.getNumberOfPages(); pageIndex++) {
|
for (int pageIndex = 0; pageIndex < sourceDocument.getNumberOfPages(); pageIndex++) {
|
||||||
@@ -121,7 +130,8 @@ public class SplitPdfBySizeController {
|
|||||||
PDDocument sourceDocument, int pageCount, ZipOutputStream zipOut, String baseFilename)
|
PDDocument sourceDocument, int pageCount, ZipOutputStream zipOut, String baseFilename)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
int currentPageCount = 0;
|
int currentPageCount = 0;
|
||||||
PDDocument currentDoc = new PDDocument();
|
PDDocument currentDoc =
|
||||||
|
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||||
int fileIndex = 1;
|
int fileIndex = 1;
|
||||||
for (PDPage page : sourceDocument.getPages()) {
|
for (PDPage page : sourceDocument.getPages()) {
|
||||||
currentDoc.addPage(page);
|
currentDoc.addPage(page);
|
||||||
@@ -152,7 +162,8 @@ public class SplitPdfBySizeController {
|
|||||||
int currentPageIndex = 0;
|
int currentPageIndex = 0;
|
||||||
int fileIndex = 1;
|
int fileIndex = 1;
|
||||||
for (int i = 0; i < documentCount; i++) {
|
for (int i = 0; i < documentCount; i++) {
|
||||||
PDDocument currentDoc = new PDDocument();
|
PDDocument currentDoc =
|
||||||
|
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||||
int pagesToAdd = pagesPerDocument + (i < extraPages ? 1 : 0);
|
int pagesToAdd = pagesPerDocument + (i < extraPages ? 1 : 0);
|
||||||
|
|
||||||
for (int j = 0; j < pagesToAdd; j++) {
|
for (int j = 0; j < pagesToAdd; j++) {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -23,6 +24,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFFile;
|
import stirling.software.SPDF.model.api.PDFFile;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -32,6 +34,13 @@ public class ToSinglePageController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ToSinglePageController.class);
|
private static final Logger logger = LoggerFactory.getLogger(ToSinglePageController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ToSinglePageController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/pdf-to-single-page")
|
@PostMapping(consumes = "multipart/form-data", value = "/pdf-to-single-page")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert a multi-page PDF into a single long page PDF",
|
summary = "Convert a multi-page PDF into a single long page PDF",
|
||||||
@@ -53,7 +62,8 @@ public class ToSinglePageController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create new document and page with calculated dimensions
|
// Create new document and page with calculated dimensions
|
||||||
PDDocument newDocument = new PDDocument();
|
PDDocument newDocument =
|
||||||
|
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDocument);
|
||||||
PDPage newPage = new PDPage(new PDRectangle(maxWidth, totalHeight));
|
PDPage newPage = new PDPage(new PDRectangle(maxWidth, totalHeight));
|
||||||
newDocument.addPage(newPage);
|
newDocument.addPage(newPage);
|
||||||
|
|
||||||
|
|||||||
@@ -208,8 +208,8 @@ public class UserController {
|
|||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@PostMapping("/admin/saveUser")
|
@PostMapping("/admin/saveUser")
|
||||||
public RedirectView saveUser(
|
public RedirectView saveUser(
|
||||||
@RequestParam String username,
|
@RequestParam(name = "username", required = true) String username,
|
||||||
@RequestParam(name = "password", required = false) String password,
|
@RequestParam(name = "password", required = true) String password,
|
||||||
@RequestParam(name = "role") String role,
|
@RequestParam(name = "role") String role,
|
||||||
@RequestParam(name = "authType") String authType,
|
@RequestParam(name = "authType") String authType,
|
||||||
@RequestParam(name = "forceChange", required = false, defaultValue = "false")
|
@RequestParam(name = "forceChange", required = false, defaultValue = "false")
|
||||||
|
|||||||
@@ -1,30 +1,36 @@
|
|||||||
package stirling.software.SPDF.controller.api.converters;
|
package stirling.software.SPDF.controller.api.converters;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.GeneralFile;
|
import stirling.software.SPDF.model.api.GeneralFile;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.FileToPdf;
|
import stirling.software.SPDF.utils.FileToPdf;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
// Disabled for now
|
||||||
@Tag(name = "Convert", description = "Convert APIs")
|
// @RestController
|
||||||
@RequestMapping("/api/v1/convert")
|
// @Tag(name = "Convert", description = "Convert APIs")
|
||||||
|
// @RequestMapping("/api/v1/convert")
|
||||||
public class ConvertBookToPDFController {
|
public class ConvertBookToPDFController {
|
||||||
|
|
||||||
@Autowired
|
private final boolean bookAndHtmlFormatsInstalled;
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
|
||||||
private boolean bookAndHtmlFormatsInstalled;
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
// @Autowired
|
||||||
|
public ConvertBookToPDFController(
|
||||||
|
CustomPDDocumentFactory pdfDocumentFactory,
|
||||||
|
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/book/pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/book/pdf")
|
||||||
@Operation(
|
@Operation(
|
||||||
|
|||||||
@@ -1,28 +1,25 @@
|
|||||||
package stirling.software.SPDF.controller.api.converters;
|
package stirling.software.SPDF.controller.api.converters;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
||||||
import stirling.software.SPDF.utils.FileToPdf;
|
import stirling.software.SPDF.utils.FileToPdf;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
// Disabled for now
|
||||||
@Tag(name = "Convert", description = "Convert APIs")
|
// @RestController
|
||||||
@RequestMapping("/api/v1/convert")
|
// @Tag(name = "Convert", description = "Convert APIs")
|
||||||
|
// @RequestMapping("/api/v1/convert")
|
||||||
public class ConvertHtmlToPDF {
|
public class ConvertHtmlToPDF {
|
||||||
|
|
||||||
@Autowired
|
// @Autowired
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||||
private boolean bookAndHtmlFormatsInstalled;
|
private boolean bookAndHtmlFormatsInstalled;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.apache.commons.io.FileUtils;
|
|||||||
import org.apache.pdfbox.rendering.ImageType;
|
import org.apache.pdfbox.rendering.ImageType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -30,6 +31,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.ConvertToImageRequest;
|
import stirling.software.SPDF.model.api.converters.ConvertToImageRequest;
|
||||||
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.CheckProgramInstall;
|
import stirling.software.SPDF.utils.CheckProgramInstall;
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
@@ -43,6 +45,13 @@ public class ConvertImgPDFController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ConvertImgPDFController.class);
|
private static final Logger logger = LoggerFactory.getLogger(ConvertImgPDFController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ConvertImgPDFController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/pdf/img")
|
@PostMapping(consumes = "multipart/form-data", value = "/pdf/img")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert PDF to image(s)",
|
summary = "Convert PDF to image(s)",
|
||||||
@@ -178,7 +187,8 @@ public class ConvertImgPDFController {
|
|||||||
boolean autoRotate = request.isAutoRotate();
|
boolean autoRotate = request.isAutoRotate();
|
||||||
|
|
||||||
// Convert the file to PDF and get the resulting bytes
|
// Convert the file to PDF and get the resulting bytes
|
||||||
byte[] bytes = PdfUtils.imageToPdf(file, fitOption, autoRotate, colorType);
|
byte[] bytes =
|
||||||
|
PdfUtils.imageToPdf(file, fitOption, autoRotate, colorType, pdfDocumentFactory);
|
||||||
return WebResponseUtils.bytesToWebResponse(
|
return WebResponseUtils.bytesToWebResponse(
|
||||||
bytes,
|
bytes,
|
||||||
file[0].getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_converted.pdf");
|
file[0].getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_converted.pdf");
|
||||||
|
|||||||
@@ -10,29 +10,26 @@ import org.commonmark.node.Node;
|
|||||||
import org.commonmark.parser.Parser;
|
import org.commonmark.parser.Parser;
|
||||||
import org.commonmark.renderer.html.AttributeProvider;
|
import org.commonmark.renderer.html.AttributeProvider;
|
||||||
import org.commonmark.renderer.html.HtmlRenderer;
|
import org.commonmark.renderer.html.HtmlRenderer;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.GeneralFile;
|
import stirling.software.SPDF.model.api.GeneralFile;
|
||||||
import stirling.software.SPDF.utils.FileToPdf;
|
import stirling.software.SPDF.utils.FileToPdf;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
// Disabled for now
|
||||||
@Tag(name = "Convert", description = "Convert APIs")
|
// @RestController
|
||||||
@RequestMapping("/api/v1/convert")
|
// @Tag(name = "Convert", description = "Convert APIs")
|
||||||
|
// @RequestMapping("/api/v1/convert")
|
||||||
public class ConvertMarkdownToPdf {
|
public class ConvertMarkdownToPdf {
|
||||||
|
|
||||||
@Autowired
|
// @Autowired
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||||
private boolean bookAndHtmlFormatsInstalled;
|
private boolean bookAndHtmlFormatsInstalled;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.SPDF.controller.api.converters;
|
package stirling.software.SPDF.controller.api.converters;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@@ -8,6 +9,8 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -20,6 +23,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.GeneralFile;
|
import stirling.software.SPDF.model.api.GeneralFile;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
@@ -29,7 +33,7 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
@RequestMapping("/api/v1/convert")
|
@RequestMapping("/api/v1/convert")
|
||||||
public class ConvertOfficeController {
|
public class ConvertOfficeController {
|
||||||
|
|
||||||
public byte[] convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
|
public File convertToPdf(MultipartFile inputFile) throws IOException, InterruptedException {
|
||||||
// Check for valid file extension
|
// Check for valid file extension
|
||||||
String originalFilename = Filenames.toSimpleFileName(inputFile.getOriginalFilename());
|
String originalFilename = Filenames.toSimpleFileName(inputFile.getOriginalFilename());
|
||||||
if (originalFilename == null
|
if (originalFilename == null
|
||||||
@@ -62,12 +66,10 @@ public class ConvertOfficeController {
|
|||||||
.runCommandWithOutputHandling(command);
|
.runCommandWithOutputHandling(command);
|
||||||
|
|
||||||
// Read the converted PDF file
|
// Read the converted PDF file
|
||||||
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
return tempOutputFile.toFile();
|
||||||
return pdfBytes;
|
|
||||||
} finally {
|
} finally {
|
||||||
// Clean up the temporary files
|
// Clean up the temporary files
|
||||||
if (tempInputFile != null) Files.deleteIfExists(tempInputFile);
|
if (tempInputFile != null) Files.deleteIfExists(tempInputFile);
|
||||||
Files.deleteIfExists(tempOutputFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +78,13 @@ public class ConvertOfficeController {
|
|||||||
return fileExtension.matches(extensionPattern);
|
return fileExtension.matches(extensionPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ConvertOfficeController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/file/pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/file/pdf")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert a file to a PDF using LibreOffice",
|
summary = "Convert a file to a PDF using LibreOffice",
|
||||||
@@ -86,12 +95,18 @@ public class ConvertOfficeController {
|
|||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
// unused but can start server instance if startup time is to long
|
// unused but can start server instance if startup time is to long
|
||||||
// LibreOfficeListener.getInstance().start();
|
// LibreOfficeListener.getInstance().start();
|
||||||
|
File file = null;
|
||||||
|
try {
|
||||||
|
file = convertToPdf(inputFile);
|
||||||
|
|
||||||
byte[] pdfByteArray = convertToPdf(inputFile);
|
PDDocument doc = pdfDocumentFactory.load(file);
|
||||||
return WebResponseUtils.bytesToWebResponse(
|
return WebResponseUtils.pdfDocToWebResponse(
|
||||||
pdfByteArray,
|
doc,
|
||||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||||
.replaceFirst("[.][^.]+$", "")
|
.replaceFirst("[.][^.]+$", "")
|
||||||
+ "_convertedToPDF.pdf");
|
+ "_convertedToPDF.pdf");
|
||||||
|
} finally {
|
||||||
|
if (file != null) file.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,30 +6,27 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToBookRequest;
|
import stirling.software.SPDF.model.api.converters.PdfToBookRequest;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
// Disabled for now
|
||||||
@Tag(name = "Convert", description = "Convert APIs")
|
// @RestController
|
||||||
@RequestMapping("/api/v1/convert")
|
// @Tag(name = "Convert", description = "Convert APIs")
|
||||||
|
// @RequestMapping("/api/v1/convert")
|
||||||
public class ConvertPDFToBookController {
|
public class ConvertPDFToBookController {
|
||||||
|
|
||||||
@Autowired
|
// @Autowired
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled")
|
@Qualifier("bookAndHtmlFormatsInstalled")
|
||||||
private boolean bookAndHtmlFormatsInstalled;
|
private boolean bookAndHtmlFormatsInstalled;
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||||
@@ -17,6 +16,7 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -29,6 +29,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToPdfARequest;
|
import stirling.software.SPDF.model.api.converters.PdfToPdfARequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
@@ -40,6 +41,13 @@ public class ConvertPDFToPDFA {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ConvertPDFToPDFA.class);
|
private static final Logger logger = LoggerFactory.getLogger(ConvertPDFToPDFA.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ConvertPDFToPDFA(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/pdf/pdfa")
|
@PostMapping(consumes = "multipart/form-data", value = "/pdf/pdfa")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert a PDF to a PDF/A",
|
summary = "Convert a PDF to a PDF/A",
|
||||||
@@ -54,7 +62,7 @@ public class ConvertPDFToPDFA {
|
|||||||
byte[] pdfBytes = inputFile.getBytes();
|
byte[] pdfBytes = inputFile.getBytes();
|
||||||
|
|
||||||
// Load the PDF document
|
// Load the PDF document
|
||||||
PDDocument document = Loader.loadPDF(pdfBytes);
|
PDDocument document = pdfDocumentFactory.load(pdfBytes);
|
||||||
|
|
||||||
// Get the document catalog
|
// Get the document catalog
|
||||||
PDDocumentCatalog catalog = document.getDocumentCatalog();
|
PDDocumentCatalog catalog = document.getDocumentCatalog();
|
||||||
@@ -101,18 +109,18 @@ public class ConvertPDFToPDFA {
|
|||||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.OCR_MY_PDF)
|
ProcessExecutor.getInstance(ProcessExecutor.Processes.OCR_MY_PDF)
|
||||||
.runCommandWithOutputHandling(command);
|
.runCommandWithOutputHandling(command);
|
||||||
|
|
||||||
// Read the optimized PDF file
|
try {
|
||||||
byte[] optimizedPdfBytes = Files.readAllBytes(tempOutputFile);
|
PDDocument doc = pdfDocumentFactory.load(tempOutputFile.toFile());
|
||||||
|
// Return the optimized PDF as a response
|
||||||
// Clean up the temporary files
|
String outputFilename =
|
||||||
Files.deleteIfExists(tempInputFile);
|
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||||
Files.deleteIfExists(tempOutputFile);
|
.replaceFirst("[.][^.]+$", "")
|
||||||
|
+ "_PDFA.pdf";
|
||||||
// Return the optimized PDF as a response
|
return WebResponseUtils.pdfDocToWebResponse(doc, outputFilename);
|
||||||
String outputFilename =
|
} finally {
|
||||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
// Clean up the temporary files
|
||||||
.replaceFirst("[.][^.]+$", "")
|
Files.deleteIfExists(tempInputFile);
|
||||||
+ "_PDFA.pdf";
|
Files.deleteIfExists(tempOutputFile);
|
||||||
return WebResponseUtils.bytesToWebResponse(optimizedPdfBytes, outputFilename);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import java.nio.file.Path;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -16,6 +20,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||||
@@ -26,6 +31,15 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
@RequestMapping("/api/v1/convert")
|
@RequestMapping("/api/v1/convert")
|
||||||
public class ConvertWebsiteToPDF {
|
public class ConvertWebsiteToPDF {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(ConvertWebsiteToPDF.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ConvertWebsiteToPDF(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/url/pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/url/pdf")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Convert a URL to a PDF",
|
summary = "Convert a URL to a PDF",
|
||||||
@@ -46,12 +60,12 @@ public class ConvertWebsiteToPDF {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Path tempOutputFile = null;
|
Path tempOutputFile = null;
|
||||||
byte[] pdfBytes;
|
PDDocument doc = null;
|
||||||
try {
|
try {
|
||||||
// Prepare the output file path
|
// Prepare the output file path
|
||||||
tempOutputFile = Files.createTempFile("output_", ".pdf");
|
tempOutputFile = Files.createTempFile("output_", ".pdf");
|
||||||
|
|
||||||
// Prepare the OCRmyPDF command
|
// Prepare the WeasyPrint command
|
||||||
List<String> command = new ArrayList<>();
|
List<String> command = new ArrayList<>();
|
||||||
command.add("weasyprint");
|
command.add("weasyprint");
|
||||||
command.add(URL);
|
command.add(URL);
|
||||||
@@ -61,16 +75,23 @@ public class ConvertWebsiteToPDF {
|
|||||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.WEASYPRINT)
|
ProcessExecutor.getInstance(ProcessExecutor.Processes.WEASYPRINT)
|
||||||
.runCommandWithOutputHandling(command);
|
.runCommandWithOutputHandling(command);
|
||||||
|
|
||||||
// Read the optimized PDF file
|
// Load the PDF using pdfDocumentFactory
|
||||||
pdfBytes = Files.readAllBytes(tempOutputFile);
|
doc = pdfDocumentFactory.load(tempOutputFile.toFile());
|
||||||
} finally {
|
|
||||||
// Clean up the temporary files
|
|
||||||
Files.deleteIfExists(tempOutputFile);
|
|
||||||
}
|
|
||||||
// Convert URL to a safe filename
|
|
||||||
String outputFilename = convertURLToFileName(URL);
|
|
||||||
|
|
||||||
return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
|
// Convert URL to a safe filename
|
||||||
|
String outputFilename = convertURLToFileName(URL);
|
||||||
|
|
||||||
|
return WebResponseUtils.pdfDocToWebResponse(doc, outputFilename);
|
||||||
|
} finally {
|
||||||
|
|
||||||
|
if (tempOutputFile != null) {
|
||||||
|
try {
|
||||||
|
Files.deleteIfExists(tempOutputFile);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Error deleting temporary output file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String convertURLToFileName(String url) {
|
private String convertURLToFileName(String url) {
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ import stirling.software.SPDF.model.api.extract.PDFFilePage;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/convert")
|
@RequestMapping("/api/v1/convert")
|
||||||
@Tag(name = "Convert", description = "Convert APIs")
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
public class ExtractController {
|
public class ExtractCSVController {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(CropController.class);
|
private static final Logger logger = LoggerFactory.getLogger(CropController.class);
|
||||||
|
|
||||||
@PostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
|
@PostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Extracts a PDF document to csv",
|
summary = "Extracts a CSV document from a PDF",
|
||||||
description =
|
description =
|
||||||
"This operation takes an input PDF file and returns CSV file of whole page. Input:PDF Output:CSV Type:SISO")
|
"This operation takes an input PDF file and returns CSV file of whole page. Input:PDF Output:CSV Type:SISO")
|
||||||
public ResponseEntity<String> PdfToCsv(@ModelAttribute PDFFilePage form) throws Exception {
|
public ResponseEntity<String> PdfToCsv(@ModelAttribute PDFFilePage form) throws Exception {
|
||||||
@@ -12,11 +12,11 @@ import java.util.List;
|
|||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -38,6 +38,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest;
|
import stirling.software.SPDF.model.api.misc.AutoSplitPdfRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -49,6 +50,13 @@ public class AutoSplitPdfController {
|
|||||||
private static final String QR_CONTENT = "https://github.com/Stirling-Tools/Stirling-PDF";
|
private static final String QR_CONTENT = "https://github.com/Stirling-Tools/Stirling-PDF";
|
||||||
private static final String QR_CONTENT_OLD = "https://github.com/Frooodle/Stirling-PDF";
|
private static final String QR_CONTENT_OLD = "https://github.com/Frooodle/Stirling-PDF";
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AutoSplitPdfController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data")
|
@PostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Auto split PDF pages into separate documents",
|
summary = "Auto split PDF pages into separate documents",
|
||||||
@@ -59,73 +67,93 @@ public class AutoSplitPdfController {
|
|||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
boolean duplexMode = request.isDuplexMode();
|
boolean duplexMode = request.isDuplexMode();
|
||||||
|
|
||||||
PDDocument document = Loader.loadPDF(file.getBytes());
|
PDDocument document = null;
|
||||||
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
|
||||||
pdfRenderer.setSubsamplingAllowed(true);
|
|
||||||
List<PDDocument> splitDocuments = new ArrayList<>();
|
List<PDDocument> splitDocuments = new ArrayList<>();
|
||||||
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
|
Path zipFile = null;
|
||||||
|
byte[] data = null;
|
||||||
|
|
||||||
for (int page = 0; page < document.getNumberOfPages(); ++page) {
|
try {
|
||||||
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150);
|
document = pdfDocumentFactory.load(file.getInputStream());
|
||||||
String result = decodeQRCode(bim);
|
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||||
if ((QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result)) && page != 0) {
|
pdfRenderer.setSubsamplingAllowed(true);
|
||||||
splitDocuments.add(new PDDocument());
|
|
||||||
|
for (int page = 0; page < document.getNumberOfPages(); ++page) {
|
||||||
|
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 150);
|
||||||
|
String result = decodeQRCode(bim);
|
||||||
|
if ((QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result)) && page != 0) {
|
||||||
|
splitDocuments.add(new PDDocument());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!splitDocuments.isEmpty()
|
||||||
|
&& !QR_CONTENT.equals(result)
|
||||||
|
&& !QR_CONTENT_OLD.equals(result)) {
|
||||||
|
splitDocuments.get(splitDocuments.size() - 1).addPage(document.getPage(page));
|
||||||
|
} else if (page == 0) {
|
||||||
|
PDDocument firstDocument = new PDDocument();
|
||||||
|
firstDocument.addPage(document.getPage(page));
|
||||||
|
splitDocuments.add(firstDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If duplexMode is true and current page is a divider, then skip next page
|
||||||
|
if (duplexMode && (QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result))) {
|
||||||
|
page++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!splitDocuments.isEmpty()
|
// Remove split documents that have no pages
|
||||||
&& !QR_CONTENT.equals(result)
|
splitDocuments.removeIf(pdDocument -> pdDocument.getNumberOfPages() == 0);
|
||||||
&& !QR_CONTENT_OLD.equals(result)) {
|
|
||||||
splitDocuments.get(splitDocuments.size() - 1).addPage(document.getPage(page));
|
zipFile = Files.createTempFile("split_documents", ".zip");
|
||||||
} else if (page == 0) {
|
String filename =
|
||||||
PDDocument firstDocument = new PDDocument();
|
Filenames.toSimpleFileName(file.getOriginalFilename())
|
||||||
firstDocument.addPage(document.getPage(page));
|
.replaceFirst("[.][^.]+$", "");
|
||||||
splitDocuments.add(firstDocument);
|
|
||||||
|
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
|
||||||
|
for (int i = 0; i < splitDocuments.size(); i++) {
|
||||||
|
String fileName = filename + "_" + (i + 1) + ".pdf";
|
||||||
|
PDDocument splitDocument = splitDocuments.get(i);
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
splitDocument.save(baos);
|
||||||
|
byte[] pdf = baos.toByteArray();
|
||||||
|
|
||||||
|
ZipEntry pdfEntry = new ZipEntry(fileName);
|
||||||
|
zipOut.putNextEntry(pdfEntry);
|
||||||
|
zipOut.write(pdf);
|
||||||
|
zipOut.closeEntry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If duplexMode is true and current page is a divider, then skip next page
|
|
||||||
if (duplexMode && (QR_CONTENT.equals(result) || QR_CONTENT_OLD.equals(result))) {
|
|
||||||
page++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove split documents that have no pages
|
|
||||||
splitDocuments.removeIf(pdDocument -> pdDocument.getNumberOfPages() == 0);
|
|
||||||
|
|
||||||
for (PDDocument splitDocument : splitDocuments) {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
splitDocument.save(baos);
|
|
||||||
splitDocumentsBoas.add(baos);
|
|
||||||
splitDocument.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.close();
|
|
||||||
|
|
||||||
Path zipFile = Files.createTempFile("split_documents", ".zip");
|
|
||||||
String filename =
|
|
||||||
Filenames.toSimpleFileName(file.getOriginalFilename())
|
|
||||||
.replaceFirst("[.][^.]+$", "");
|
|
||||||
byte[] data;
|
|
||||||
|
|
||||||
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
|
|
||||||
for (int i = 0; i < splitDocumentsBoas.size(); i++) {
|
|
||||||
String fileName = filename + "_" + (i + 1) + ".pdf";
|
|
||||||
ByteArrayOutputStream baos = splitDocumentsBoas.get(i);
|
|
||||||
byte[] pdf = baos.toByteArray();
|
|
||||||
|
|
||||||
ZipEntry pdfEntry = new ZipEntry(fileName);
|
|
||||||
zipOut.putNextEntry(pdfEntry);
|
|
||||||
zipOut.write(pdf);
|
|
||||||
zipOut.closeEntry();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("exception", e);
|
|
||||||
} finally {
|
|
||||||
data = Files.readAllBytes(zipFile);
|
data = Files.readAllBytes(zipFile);
|
||||||
Files.deleteIfExists(zipFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return WebResponseUtils.bytesToWebResponse(
|
return WebResponseUtils.bytesToWebResponse(
|
||||||
data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM);
|
data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM);
|
||||||
|
} finally {
|
||||||
|
// Clean up resources
|
||||||
|
if (document != null) {
|
||||||
|
try {
|
||||||
|
document.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Error closing main PDDocument", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PDDocument splitDoc : splitDocuments) {
|
||||||
|
try {
|
||||||
|
splitDoc.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Error closing split PDDocument", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zipFile != null) {
|
||||||
|
try {
|
||||||
|
Files.deleteIfExists(zipFile);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Error deleting temporary zip file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String decodeQRCode(BufferedImage bufferedImage) {
|
private static String decodeQRCode(BufferedImage bufferedImage) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.apache.pdfbox.rendering.PDFRenderer;
|
|||||||
import org.apache.pdfbox.text.PDFTextStripper;
|
import org.apache.pdfbox.text.PDFTextStripper;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -30,6 +31,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.RemoveBlankPagesRequest;
|
import stirling.software.SPDF.model.api.misc.RemoveBlankPagesRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -40,6 +42,13 @@ public class BlankPageController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(BlankPageController.class);
|
private static final Logger logger = LoggerFactory.getLogger(BlankPageController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public BlankPageController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/remove-blanks")
|
@PostMapping(consumes = "multipart/form-data", value = "/remove-blanks")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Remove blank pages from a PDF file",
|
summary = "Remove blank pages from a PDF file",
|
||||||
@@ -124,7 +133,7 @@ public class BlankPageController {
|
|||||||
|
|
||||||
public void createZipEntry(ZipOutputStream zos, List<PDPage> pages, String entryName)
|
public void createZipEntry(ZipOutputStream zos, List<PDPage> pages, String entryName)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
try (PDDocument document = new PDDocument()) {
|
try (PDDocument document = pdfDocumentFactory.createNewDocument()) {
|
||||||
|
|
||||||
for (PDPage page : pages) {
|
for (PDPage page : pages) {
|
||||||
document.addPage(page);
|
document.addPage(page);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.apache.pdfbox.pdmodel.graphics.PDXObject;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -32,6 +33,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
|
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||||
@@ -44,6 +46,13 @@ public class CompressController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(CompressController.class);
|
private static final Logger logger = LoggerFactory.getLogger(CompressController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CompressController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/compress-pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/compress-pdf")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Optimize PDF file",
|
summary = "Optimize PDF file",
|
||||||
@@ -258,7 +267,7 @@ public class CompressController {
|
|||||||
}
|
}
|
||||||
// Read the optimized PDF file
|
// Read the optimized PDF file
|
||||||
pdfBytes = Files.readAllBytes(tempOutputFile);
|
pdfBytes = Files.readAllBytes(tempOutputFile);
|
||||||
|
Path finalFile = tempOutputFile;
|
||||||
// Check if optimized file is larger than the original
|
// Check if optimized file is larger than the original
|
||||||
if (pdfBytes.length > inputFileSize) {
|
if (pdfBytes.length > inputFileSize) {
|
||||||
// Log the occurrence
|
// Log the occurrence
|
||||||
@@ -266,14 +275,15 @@ public class CompressController {
|
|||||||
"Optimized file is larger than the original. Returning the original file instead.");
|
"Optimized file is larger than the original. Returning the original file instead.");
|
||||||
|
|
||||||
// Read the original file again
|
// Read the original file again
|
||||||
pdfBytes = Files.readAllBytes(tempInputFile);
|
finalFile = tempInputFile;
|
||||||
}
|
}
|
||||||
// Return the optimized PDF as a response
|
// Return the optimized PDF as a response
|
||||||
String outputFilename =
|
String outputFilename =
|
||||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
|
||||||
.replaceFirst("[.][^.]+$", "")
|
.replaceFirst("[.][^.]+$", "")
|
||||||
+ "_Optimized.pdf";
|
+ "_Optimized.pdf";
|
||||||
return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
|
return WebResponseUtils.pdfDocToWebResponse(
|
||||||
|
pdfDocumentFactory.load(finalFile.toFile()), outputFilename);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
// Clean up the temporary files
|
// Clean up the temporary files
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.apache.pdfbox.rendering.ImageType;
|
|||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -25,9 +26,8 @@ import io.github.pixee.security.Filenames;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.PdfMetadata;
|
|
||||||
import stirling.software.SPDF.model.api.misc.FlattenRequest;
|
import stirling.software.SPDF.model.api.misc.FlattenRequest;
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -37,6 +37,13 @@ public class FlattenController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(FlattenController.class);
|
private static final Logger logger = LoggerFactory.getLogger(FlattenController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public FlattenController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/flatten")
|
@PostMapping(consumes = "multipart/form-data", value = "/flatten")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Flatten PDF form fields or full page",
|
summary = "Flatten PDF form fields or full page",
|
||||||
@@ -46,7 +53,6 @@ public class FlattenController {
|
|||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
|
|
||||||
PDDocument document = Loader.loadPDF(file.getBytes());
|
PDDocument document = Loader.loadPDF(file.getBytes());
|
||||||
PdfMetadata metadata = PdfUtils.extractMetadataFromPdf(document);
|
|
||||||
Boolean flattenOnlyForms = request.getFlattenOnlyForms();
|
Boolean flattenOnlyForms = request.getFlattenOnlyForms();
|
||||||
|
|
||||||
if (Boolean.TRUE.equals(flattenOnlyForms)) {
|
if (Boolean.TRUE.equals(flattenOnlyForms)) {
|
||||||
@@ -60,7 +66,8 @@ public class FlattenController {
|
|||||||
// flatten whole page aka convert each page to image and readd it (making text
|
// flatten whole page aka convert each page to image and readd it (making text
|
||||||
// unselectable)
|
// unselectable)
|
||||||
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||||
PDDocument newDocument = new PDDocument();
|
PDDocument newDocument =
|
||||||
|
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(document);
|
||||||
int numPages = document.getNumberOfPages();
|
int numPages = document.getNumberOfPages();
|
||||||
for (int i = 0; i < numPages; i++) {
|
for (int i = 0; i < numPages; i++) {
|
||||||
try {
|
try {
|
||||||
@@ -80,7 +87,6 @@ public class FlattenController {
|
|||||||
logger.error("exception", e);
|
logger.error("exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PdfUtils.setMetadataToPdf(newDocument, metadata);
|
|
||||||
return WebResponseUtils.pdfDocToWebResponse(
|
return WebResponseUtils.pdfDocToWebResponse(
|
||||||
newDocument, Filenames.toSimpleFileName(file.getOriginalFilename()));
|
newDocument, Filenames.toSimpleFileName(file.getOriginalFilename()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.SPDF.controller.api.misc;
|
package stirling.software.SPDF.controller.api.misc;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -28,6 +29,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
|
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.api.misc.ProcessPdfWithOcrRequest;
|
import stirling.software.SPDF.model.api.misc.ProcessPdfWithOcrRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
@@ -52,6 +54,13 @@ public class OCRController {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public OCRController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/ocr-pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/ocr-pdf")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Process a PDF file with OCR",
|
summary = "Process a PDF file with OCR",
|
||||||
@@ -175,7 +184,7 @@ public class OCRController {
|
|||||||
tempOutputFile = tempPdfWithoutImages;
|
tempOutputFile = tempPdfWithoutImages;
|
||||||
}
|
}
|
||||||
// Read the OCR processed PDF file
|
// Read the OCR processed PDF file
|
||||||
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
|
byte[] pdfBytes = pdfDocumentFactory.loadToBytes(tempOutputFile.toFile());
|
||||||
|
|
||||||
// Return the OCR processed PDF as a response
|
// Return the OCR processed PDF as a response
|
||||||
String outputFilename =
|
String outputFilename =
|
||||||
@@ -196,7 +205,13 @@ public class OCRController {
|
|||||||
// Add PDF file to the zip
|
// Add PDF file to the zip
|
||||||
ZipEntry pdfEntry = new ZipEntry(outputFilename);
|
ZipEntry pdfEntry = new ZipEntry(outputFilename);
|
||||||
zipOut.putNextEntry(pdfEntry);
|
zipOut.putNextEntry(pdfEntry);
|
||||||
Files.copy(tempOutputFile, zipOut);
|
try (ByteArrayInputStream pdfInputStream = new ByteArrayInputStream(pdfBytes)) {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int length;
|
||||||
|
while ((length = pdfInputStream.read(buffer)) != -1) {
|
||||||
|
zipOut.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
zipOut.closeEntry();
|
zipOut.closeEntry();
|
||||||
|
|
||||||
// Add text file to the zip
|
// Add text file to the zip
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -17,6 +18,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.OverlayImageRequest;
|
import stirling.software.SPDF.model.api.misc.OverlayImageRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -27,6 +29,13 @@ public class OverlayImageController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(OverlayImageController.class);
|
private static final Logger logger = LoggerFactory.getLogger(OverlayImageController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public OverlayImageController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/add-image")
|
@PostMapping(consumes = "multipart/form-data", value = "/add-image")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Overlay image onto a PDF file",
|
summary = "Overlay image onto a PDF file",
|
||||||
@@ -41,7 +50,9 @@ public class OverlayImageController {
|
|||||||
try {
|
try {
|
||||||
byte[] pdfBytes = pdfFile.getBytes();
|
byte[] pdfBytes = pdfFile.getBytes();
|
||||||
byte[] imageBytes = imageFile.getBytes();
|
byte[] imageBytes = imageFile.getBytes();
|
||||||
byte[] result = PdfUtils.overlayImage(pdfBytes, imageBytes, x, y, everyPage);
|
byte[] result =
|
||||||
|
PdfUtils.overlayImage(
|
||||||
|
pdfDocumentFactory, pdfBytes, imageBytes, x, y, everyPage);
|
||||||
|
|
||||||
return WebResponseUtils.bytesToWebResponse(
|
return WebResponseUtils.bytesToWebResponse(
|
||||||
result,
|
result,
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
@@ -13,6 +12,7 @@ import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
|||||||
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
|
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -26,6 +26,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.AddPageNumbersRequest;
|
import stirling.software.SPDF.model.api.misc.AddPageNumbersRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.GeneralUtils;
|
import stirling.software.SPDF.utils.GeneralUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -36,6 +37,13 @@ public class PageNumbersController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PageNumbersController.class);
|
private static final Logger logger = LoggerFactory.getLogger(PageNumbersController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public PageNumbersController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/add-page-numbers", consumes = "multipart/form-data")
|
@PostMapping(value = "/add-page-numbers", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Add page numbers to a PDF document",
|
summary = "Add page numbers to a PDF document",
|
||||||
@@ -52,7 +60,7 @@ public class PageNumbersController {
|
|||||||
String customText = request.getCustomText();
|
String customText = request.getCustomText();
|
||||||
int pageNumber = startingNumber;
|
int pageNumber = startingNumber;
|
||||||
byte[] fileBytes = file.getBytes();
|
byte[] fileBytes = file.getBytes();
|
||||||
PDDocument document = Loader.loadPDF(fileBytes);
|
PDDocument document = pdfDocumentFactory.load(fileBytes);
|
||||||
float font_size = request.getFontSize();
|
float font_size = request.getFontSize();
|
||||||
String font_type = request.getFontType();
|
String font_type = request.getFontType();
|
||||||
float marginFactor;
|
float marginFactor;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -20,6 +21,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFFile;
|
import stirling.software.SPDF.model.api.PDFFile;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor;
|
import stirling.software.SPDF.utils.ProcessExecutor;
|
||||||
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
@@ -31,6 +33,13 @@ public class RepairController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RepairController.class);
|
private static final Logger logger = LoggerFactory.getLogger(RepairController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RepairController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/repair")
|
@PostMapping(consumes = "multipart/form-data", value = "/repair")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Repair a PDF file",
|
summary = "Repair a PDF file",
|
||||||
@@ -58,7 +67,7 @@ public class RepairController {
|
|||||||
.runCommandWithOutputHandling(command);
|
.runCommandWithOutputHandling(command);
|
||||||
|
|
||||||
// Read the optimized PDF file
|
// Read the optimized PDF file
|
||||||
pdfBytes = Files.readAllBytes(tempOutputFile);
|
pdfBytes = pdfDocumentFactory.loadToBytes(tempOutputFile.toFile());
|
||||||
|
|
||||||
// Return the optimized PDF as a response
|
// Return the optimized PDF as a response
|
||||||
String outputFilename =
|
String outputFilename =
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.apache.pdfbox.pdmodel.common.PDNameTreeNode;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
|
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -75,7 +76,8 @@ public class ShowJavascript {
|
|||||||
|
|
||||||
return WebResponseUtils.bytesToWebResponse(
|
return WebResponseUtils.bytesToWebResponse(
|
||||||
script.getBytes(StandardCharsets.UTF_8),
|
script.getBytes(StandardCharsets.UTF_8),
|
||||||
Filenames.toSimpleFileName(inputFile.getOriginalFilename()) + ".js");
|
Filenames.toSimpleFileName(inputFile.getOriginalFilename()) + ".js",
|
||||||
|
MediaType.TEXT_PLAIN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import java.util.List;
|
|||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
@@ -25,6 +24,7 @@ import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -38,6 +38,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.AddStampRequest;
|
import stirling.software.SPDF.model.api.misc.AddStampRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -45,6 +46,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
@Tag(name = "Misc", description = "Miscellaneous APIs")
|
||||||
public class StampController {
|
public class StampController {
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public StampController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/add-stamp")
|
@PostMapping(consumes = "multipart/form-data", value = "/add-stamp")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Add stamp to a PDF file",
|
summary = "Add stamp to a PDF file",
|
||||||
@@ -86,7 +94,7 @@ public class StampController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load the input PDF
|
// Load the input PDF
|
||||||
PDDocument document = Loader.loadPDF(pdfFile.getBytes());
|
PDDocument document = pdfDocumentFactory.load(pdfFile);
|
||||||
|
|
||||||
List<Integer> pageNumbers = request.getPageNumbersList(document, true);
|
List<Integer> pageNumbers = request.getPageNumbersList(document, true);
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,6 @@ package stirling.software.SPDF.controller.api.pipeline;
|
|||||||
|
|
||||||
public interface UserServiceInterface {
|
public interface UserServiceInterface {
|
||||||
String getApiKeyForUser(String username);
|
String getApiKeyForUser(String username);
|
||||||
|
|
||||||
|
String getCurrentUsername();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import java.security.cert.CertificateException;
|
|||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.examples.signature.CreateSignatureBase;
|
import org.apache.pdfbox.examples.signature.CreateSignatureBase;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
|
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
|
||||||
@@ -35,6 +34,7 @@ import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
|
|||||||
import org.bouncycastle.pkcs.PKCSException;
|
import org.bouncycastle.pkcs.PKCSException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -47,6 +47,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.security.SignPDFWithCertRequest;
|
import stirling.software.SPDF.model.api.security.SignPDFWithCertRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -71,6 +72,13 @@ public class CertSignController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CertSignController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
|
@PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Sign PDF with a Digital Certificate",
|
summary = "Sign PDF with a Digital Certificate",
|
||||||
@@ -122,7 +130,7 @@ public class CertSignController {
|
|||||||
|
|
||||||
CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());
|
CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
sign(pdf.getBytes(), baos, createSignature, name, location, reason);
|
sign(pdfDocumentFactory, pdf.getBytes(), baos, createSignature, name, location, reason);
|
||||||
return WebResponseUtils.boasToWebResponse(
|
return WebResponseUtils.boasToWebResponse(
|
||||||
baos,
|
baos,
|
||||||
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||||
@@ -130,13 +138,14 @@ public class CertSignController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void sign(
|
private static void sign(
|
||||||
|
CustomPDDocumentFactory pdfDocumentFactory,
|
||||||
byte[] input,
|
byte[] input,
|
||||||
OutputStream output,
|
OutputStream output,
|
||||||
CreateSignature instance,
|
CreateSignature instance,
|
||||||
String name,
|
String name,
|
||||||
String location,
|
String location,
|
||||||
String reason) {
|
String reason) {
|
||||||
try (PDDocument doc = Loader.loadPDF(input)) {
|
try (PDDocument doc = pdfDocumentFactory.load(input)) {
|
||||||
PDSignature signature = new PDSignature();
|
PDSignature signature = new PDSignature();
|
||||||
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
|
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
|
||||||
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
|
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package stirling.software.SPDF.controller.api.security;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
|
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
|
||||||
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
|
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
|
|
||||||
import stirling.software.SPDF.model.api.security.AddPasswordRequest;
|
import stirling.software.SPDF.model.api.security.AddPasswordRequest;
|
||||||
import stirling.software.SPDF.model.api.security.PDFPasswordRequest;
|
import stirling.software.SPDF.model.api.security.PDFPasswordRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -30,6 +31,13 @@ public class PasswordController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PasswordController.class);
|
private static final Logger logger = LoggerFactory.getLogger(PasswordController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public PasswordController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/remove-password")
|
@PostMapping(consumes = "multipart/form-data", value = "/remove-password")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Remove password from a PDF file",
|
summary = "Remove password from a PDF file",
|
||||||
@@ -39,8 +47,7 @@ public class PasswordController {
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
MultipartFile fileInput = request.getFileInput();
|
MultipartFile fileInput = request.getFileInput();
|
||||||
String password = request.getPassword();
|
String password = request.getPassword();
|
||||||
|
PDDocument document = pdfDocumentFactory.load(fileInput, password);
|
||||||
PDDocument document = Loader.loadPDF(fileInput.getBytes(), password);
|
|
||||||
document.setAllSecurityToBeRemoved(true);
|
document.setAllSecurityToBeRemoved(true);
|
||||||
return WebResponseUtils.pdfDocToWebResponse(
|
return WebResponseUtils.pdfDocToWebResponse(
|
||||||
document,
|
document,
|
||||||
@@ -69,7 +76,7 @@ public class PasswordController {
|
|||||||
boolean canPrint = request.isCanPrint();
|
boolean canPrint = request.isCanPrint();
|
||||||
boolean canPrintFaithful = request.isCanPrintFaithful();
|
boolean canPrintFaithful = request.isCanPrintFaithful();
|
||||||
|
|
||||||
PDDocument document = Loader.loadPDF(fileInput.getBytes());
|
PDDocument document = pdfDocumentFactory.load(fileInput);
|
||||||
AccessPermission ap = new AccessPermission();
|
AccessPermission ap = new AccessPermission();
|
||||||
ap.setCanAssembleDocument(!canAssembleDocument);
|
ap.setCanAssembleDocument(!canAssembleDocument);
|
||||||
ap.setCanExtractContent(!canExtractContent);
|
ap.setCanExtractContent(!canExtractContent);
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -25,6 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
import stirling.software.SPDF.model.PDFText;
|
import stirling.software.SPDF.model.PDFText;
|
||||||
import stirling.software.SPDF.model.api.security.RedactPdfRequest;
|
import stirling.software.SPDF.model.api.security.RedactPdfRequest;
|
||||||
import stirling.software.SPDF.pdf.TextFinder;
|
import stirling.software.SPDF.pdf.TextFinder;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -35,6 +36,13 @@ public class RedactController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RedactController.class);
|
private static final Logger logger = LoggerFactory.getLogger(RedactController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RedactController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/auto-redact", consumes = "multipart/form-data")
|
@PostMapping(value = "/auto-redact", consumes = "multipart/form-data")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Redacts listOfText in a PDF document",
|
summary = "Redacts listOfText in a PDF document",
|
||||||
@@ -52,8 +60,7 @@ public class RedactController {
|
|||||||
|
|
||||||
System.out.println(listOfTextString);
|
System.out.println(listOfTextString);
|
||||||
String[] listOfText = listOfTextString.split("\n");
|
String[] listOfText = listOfTextString.split("\n");
|
||||||
byte[] bytes = file.getBytes();
|
PDDocument document = pdfDocumentFactory.load(file);
|
||||||
PDDocument document = Loader.loadPDF(bytes);
|
|
||||||
|
|
||||||
Color redactColor;
|
Color redactColor;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package stirling.software.SPDF.controller.api.security;
|
package stirling.software.SPDF.controller.api.security;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||||
@@ -12,6 +10,7 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -24,6 +23,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFFile;
|
import stirling.software.SPDF.model.api.PDFFile;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -33,6 +33,13 @@ public class RemoveCertSignController {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RemoveCertSignController.class);
|
private static final Logger logger = LoggerFactory.getLogger(RemoveCertSignController.class);
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RemoveCertSignController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/remove-cert-sign")
|
@PostMapping(consumes = "multipart/form-data", value = "/remove-cert-sign")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Remove digital signature from PDF",
|
summary = "Remove digital signature from PDF",
|
||||||
@@ -42,14 +49,8 @@ public class RemoveCertSignController {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile pdf = request.getFileInput();
|
MultipartFile pdf = request.getFileInput();
|
||||||
|
|
||||||
// Convert MultipartFile to byte[]
|
|
||||||
byte[] pdfBytes = pdf.getBytes();
|
|
||||||
|
|
||||||
// Create a ByteArrayOutputStream to hold the resulting PDF
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
// Load the PDF document
|
// Load the PDF document
|
||||||
PDDocument document = Loader.loadPDF(pdfBytes);
|
PDDocument document = pdfDocumentFactory.load(pdf);
|
||||||
|
|
||||||
// Get the document catalog
|
// Get the document catalog
|
||||||
PDDocumentCatalog catalog = document.getDocumentCatalog();
|
PDDocumentCatalog catalog = document.getDocumentCatalog();
|
||||||
@@ -67,14 +68,9 @@ public class RemoveCertSignController {
|
|||||||
acroForm.flatten(fieldsToRemove, false);
|
acroForm.flatten(fieldsToRemove, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the modified document to the ByteArrayOutputStream
|
|
||||||
document.save(baos);
|
|
||||||
document.close();
|
|
||||||
|
|
||||||
// Return the modified PDF as a response
|
// Return the modified PDF as a response
|
||||||
return WebResponseUtils.boasToWebResponse(
|
return WebResponseUtils.pdfDocToWebResponse(
|
||||||
baos,
|
document,
|
||||||
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
|
||||||
+ "_unsigned.pdf");
|
+ "_unsigned.pdf");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package stirling.software.SPDF.controller.api.security;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.cos.COSDictionary;
|
import org.apache.pdfbox.cos.COSDictionary;
|
||||||
import org.apache.pdfbox.cos.COSName;
|
import org.apache.pdfbox.cos.COSName;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
@@ -21,6 +20,7 @@ import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
|
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -33,6 +33,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.security.SanitizePdfRequest;
|
import stirling.software.SPDF.model.api.security.SanitizePdfRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -40,6 +41,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
@Tag(name = "Security", description = "Security APIs")
|
@Tag(name = "Security", description = "Security APIs")
|
||||||
public class SanitizeController {
|
public class SanitizeController {
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SanitizeController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/sanitize-pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/sanitize-pdf")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Sanitize a PDF file",
|
summary = "Sanitize a PDF file",
|
||||||
@@ -54,7 +62,7 @@ public class SanitizeController {
|
|||||||
boolean removeLinks = request.isRemoveLinks();
|
boolean removeLinks = request.isRemoveLinks();
|
||||||
boolean removeFonts = request.isRemoveFonts();
|
boolean removeFonts = request.isRemoveFonts();
|
||||||
|
|
||||||
PDDocument document = Loader.loadPDF(inputFile.getBytes());
|
PDDocument document = pdfDocumentFactory.load(inputFile);
|
||||||
if (removeJavaScript) {
|
if (removeJavaScript) {
|
||||||
sanitizeJavaScript(document);
|
sanitizeJavaScript(document);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import java.nio.file.Files;
|
|||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.pdfbox.Loader;
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
@@ -23,6 +22,7 @@ import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -36,6 +36,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.security.AddWatermarkRequest;
|
import stirling.software.SPDF.model.api.security.AddWatermarkRequest;
|
||||||
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.PdfUtils;
|
import stirling.software.SPDF.utils.PdfUtils;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
|
|
||||||
@@ -44,6 +45,13 @@ import stirling.software.SPDF.utils.WebResponseUtils;
|
|||||||
@Tag(name = "Security", description = "Security APIs")
|
@Tag(name = "Security", description = "Security APIs")
|
||||||
public class WatermarkController {
|
public class WatermarkController {
|
||||||
|
|
||||||
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public WatermarkController(CustomPDDocumentFactory pdfDocumentFactory) {
|
||||||
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/add-watermark")
|
@PostMapping(consumes = "multipart/form-data", value = "/add-watermark")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Add watermark to a PDF file",
|
summary = "Add watermark to a PDF file",
|
||||||
@@ -64,7 +72,7 @@ public class WatermarkController {
|
|||||||
boolean convertPdfToImage = request.isConvertPDFToImage();
|
boolean convertPdfToImage = request.isConvertPDFToImage();
|
||||||
|
|
||||||
// Load the input PDF
|
// Load the input PDF
|
||||||
PDDocument document = Loader.loadPDF(pdfFile.getBytes());
|
PDDocument document = pdfDocumentFactory.load(pdfFile);
|
||||||
|
|
||||||
// Create a page in the document
|
// Create a page in the document
|
||||||
for (PDPage page : document.getPages()) {
|
for (PDPage page : document.getPages()) {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class AccountWebController {
|
|||||||
|
|
||||||
Map<String, String> providerList = new HashMap<>();
|
Map<String, String> providerList = new HashMap<>();
|
||||||
|
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOAUTH2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
if (oauth != null) {
|
if (oauth != null) {
|
||||||
if (oauth.isSettingsValid()) {
|
if (oauth.isSettingsValid()) {
|
||||||
providerList.put("oidc", oauth.getProvider());
|
providerList.put("oidc", oauth.getProvider());
|
||||||
@@ -82,7 +82,7 @@ public class AccountWebController {
|
|||||||
|
|
||||||
model.addAttribute("loginMethod", applicationProperties.getSecurity().getLoginMethod());
|
model.addAttribute("loginMethod", applicationProperties.getSecurity().getLoginMethod());
|
||||||
model.addAttribute(
|
model.addAttribute(
|
||||||
"oAuth2Enabled", applicationProperties.getSecurity().getOAUTH2().getEnabled());
|
"oAuth2Enabled", applicationProperties.getSecurity().getOauth2().getEnabled());
|
||||||
|
|
||||||
model.addAttribute("currentPage", "login");
|
model.addAttribute("currentPage", "login");
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ public class AccountWebController {
|
|||||||
// Retrieve username and other attributes
|
// Retrieve username and other attributes
|
||||||
username =
|
username =
|
||||||
userDetails.getAttribute(
|
userDetails.getAttribute(
|
||||||
applicationProperties.getSecurity().getOAUTH2().getUseAsUsername());
|
applicationProperties.getSecurity().getOauth2().getUseAsUsername());
|
||||||
// Add oAuth2 Login attributes to the model
|
// Add oAuth2 Login attributes to the model
|
||||||
model.addAttribute("oAuth2Login", true);
|
model.addAttribute("oAuth2Login", true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,7 @@ package stirling.software.SPDF.controller.web;
|
|||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Comparator;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -18,19 +14,20 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import io.micrometer.core.instrument.Counter;
|
import io.micrometer.core.instrument.Counter;
|
||||||
import io.micrometer.core.instrument.Meter;
|
|
||||||
import io.micrometer.core.instrument.MeterRegistry;
|
import io.micrometer.core.instrument.MeterRegistry;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import stirling.software.SPDF.config.StartupApplicationListener;
|
import stirling.software.SPDF.config.StartupApplicationListener;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/info")
|
@RequestMapping("/api/v1/info")
|
||||||
@Tag(name = "Info", description = "Info APIs")
|
@Tag(name = "Info", description = "Info APIs")
|
||||||
|
@Slf4j
|
||||||
public class MetricsController {
|
public class MetricsController {
|
||||||
|
|
||||||
@Autowired ApplicationProperties applicationProperties;
|
@Autowired ApplicationProperties applicationProperties;
|
||||||
@@ -46,6 +43,7 @@ public class MetricsController {
|
|||||||
this.metricsEnabled = metricsEnabled;
|
this.metricsEnabled = metricsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
public MetricsController(MeterRegistry meterRegistry) {
|
public MetricsController(MeterRegistry meterRegistry) {
|
||||||
this.meterRegistry = meterRegistry;
|
this.meterRegistry = meterRegistry;
|
||||||
}
|
}
|
||||||
@@ -66,11 +64,11 @@ public class MetricsController {
|
|||||||
return ResponseEntity.ok(status);
|
return ResponseEntity.ok(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/loads")
|
@GetMapping("/load")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "GET request count",
|
summary = "GET request count",
|
||||||
description =
|
description =
|
||||||
"This endpoint returns the total count of GET requests or the count of GET requests for a specific endpoint.")
|
"This endpoint returns the total count of GET requests for a specific endpoint or all endpoints.")
|
||||||
public ResponseEntity<?> getPageLoads(
|
public ResponseEntity<?> getPageLoads(
|
||||||
@RequestParam(required = false, name = "endpoint") @Parameter(description = "endpoint")
|
@RequestParam(required = false, name = "endpoint") @Parameter(description = "endpoint")
|
||||||
Optional<String> endpoint) {
|
Optional<String> endpoint) {
|
||||||
@@ -78,44 +76,33 @@ public class MetricsController {
|
|||||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
double count = getRequestCount("GET", endpoint);
|
||||||
double count = 0.0;
|
|
||||||
|
|
||||||
for (Meter meter : meterRegistry.getMeters()) {
|
|
||||||
if (meter.getId().getName().equals("http.requests")) {
|
|
||||||
String method = meter.getId().getTag("method");
|
|
||||||
if (method != null && "GET".equals(method)) {
|
|
||||||
|
|
||||||
if (endpoint.isPresent() && !endpoint.get().isBlank()) {
|
|
||||||
if (!endpoint.get().startsWith("/")) {
|
|
||||||
endpoint = Optional.of("/" + endpoint.get());
|
|
||||||
}
|
|
||||||
System.out.println(
|
|
||||||
"loads "
|
|
||||||
+ endpoint.get()
|
|
||||||
+ " vs "
|
|
||||||
+ meter.getId().getTag("uri"));
|
|
||||||
if (endpoint.get().equals(meter.getId().getTag("uri"))) {
|
|
||||||
if (meter instanceof Counter) {
|
|
||||||
count += ((Counter) meter).count();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (meter instanceof Counter) {
|
|
||||||
count += ((Counter) meter).count();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResponseEntity.ok(count);
|
return ResponseEntity.ok(count);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/loads/all")
|
@GetMapping("/load/unique")
|
||||||
|
@Operation(
|
||||||
|
summary = "Unique users count for GET requests",
|
||||||
|
description =
|
||||||
|
"This endpoint returns the count of unique users for GET requests for a specific endpoint or all endpoints.")
|
||||||
|
public ResponseEntity<?> getUniquePageLoads(
|
||||||
|
@RequestParam(required = false, name = "endpoint") @Parameter(description = "endpoint")
|
||||||
|
Optional<String> endpoint) {
|
||||||
|
if (!metricsEnabled) {
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
double count = getUniqueUserCount("GET", endpoint);
|
||||||
|
return ResponseEntity.ok(count);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/load/all")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "GET requests count for all endpoints",
|
summary = "GET requests count for all endpoints",
|
||||||
description = "This endpoint returns the count of GET requests for each endpoint.")
|
description = "This endpoint returns the count of GET requests for each endpoint.")
|
||||||
@@ -124,37 +111,191 @@ public class MetricsController {
|
|||||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Map<String, Double> counts = new HashMap<>();
|
List<EndpointCount> results = getEndpointCounts("GET");
|
||||||
|
|
||||||
for (Meter meter : meterRegistry.getMeters()) {
|
|
||||||
if (meter.getId().getName().equals("http.requests")) {
|
|
||||||
String method = meter.getId().getTag("method");
|
|
||||||
if (method != null && "GET".equals(method)) {
|
|
||||||
String uri = meter.getId().getTag("uri");
|
|
||||||
if (uri != null) {
|
|
||||||
double currentCount = counts.getOrDefault(uri, 0.0);
|
|
||||||
if (meter instanceof Counter) {
|
|
||||||
currentCount += ((Counter) meter).count();
|
|
||||||
}
|
|
||||||
counts.put(uri, currentCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<EndpointCount> results =
|
|
||||||
counts.entrySet().stream()
|
|
||||||
.map(entry -> new EndpointCount(entry.getKey(), entry.getValue()))
|
|
||||||
.sorted(Comparator.comparing(EndpointCount::getCount).reversed())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
return ResponseEntity.ok(results);
|
return ResponseEntity.ok(results);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EndpointCount {
|
@GetMapping("/load/all/unique")
|
||||||
|
@Operation(
|
||||||
|
summary = "Unique users count for GET requests for all endpoints",
|
||||||
|
description =
|
||||||
|
"This endpoint returns the count of unique users for GET requests for each endpoint.")
|
||||||
|
public ResponseEntity<?> getAllUniqueEndpointLoads() {
|
||||||
|
if (!metricsEnabled) {
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<EndpointCount> results = getUniqueUserCounts("GET");
|
||||||
|
return ResponseEntity.ok(results);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/requests")
|
||||||
|
@Operation(
|
||||||
|
summary = "POST request count",
|
||||||
|
description =
|
||||||
|
"This endpoint returns the total count of POST requests for a specific endpoint or all endpoints.")
|
||||||
|
public ResponseEntity<?> getTotalRequests(
|
||||||
|
@RequestParam(required = false, name = "endpoint") @Parameter(description = "endpoint")
|
||||||
|
Optional<String> endpoint) {
|
||||||
|
if (!metricsEnabled) {
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
double count = getRequestCount("POST", endpoint);
|
||||||
|
return ResponseEntity.ok(count);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ResponseEntity.ok(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/requests/unique")
|
||||||
|
@Operation(
|
||||||
|
summary = "Unique users count for POST requests",
|
||||||
|
description =
|
||||||
|
"This endpoint returns the count of unique users for POST requests for a specific endpoint or all endpoints.")
|
||||||
|
public ResponseEntity<?> getUniqueTotalRequests(
|
||||||
|
@RequestParam(required = false, name = "endpoint") @Parameter(description = "endpoint")
|
||||||
|
Optional<String> endpoint) {
|
||||||
|
if (!metricsEnabled) {
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
double count = getUniqueUserCount("POST", endpoint);
|
||||||
|
return ResponseEntity.ok(count);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ResponseEntity.ok(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/requests/all")
|
||||||
|
@Operation(
|
||||||
|
summary = "POST requests count for all endpoints",
|
||||||
|
description = "This endpoint returns the count of POST requests for each endpoint.")
|
||||||
|
public ResponseEntity<?> getAllPostRequests() {
|
||||||
|
if (!metricsEnabled) {
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<EndpointCount> results = getEndpointCounts("POST");
|
||||||
|
return ResponseEntity.ok(results);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/requests/all/unique")
|
||||||
|
@Operation(
|
||||||
|
summary = "Unique users count for POST requests for all endpoints",
|
||||||
|
description =
|
||||||
|
"This endpoint returns the count of unique users for POST requests for each endpoint.")
|
||||||
|
public ResponseEntity<?> getAllUniquePostRequests() {
|
||||||
|
if (!metricsEnabled) {
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<EndpointCount> results = getUniqueUserCounts("POST");
|
||||||
|
return ResponseEntity.ok(results);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getRequestCount(String method, Optional<String> endpoint) {
|
||||||
|
log.info(
|
||||||
|
"Getting request count for method: {}, endpoint: {}",
|
||||||
|
method,
|
||||||
|
endpoint.orElse("all"));
|
||||||
|
double count =
|
||||||
|
meterRegistry.find("http.requests").tag("method", method).counters().stream()
|
||||||
|
.filter(
|
||||||
|
counter ->
|
||||||
|
!endpoint.isPresent()
|
||||||
|
|| endpoint.get()
|
||||||
|
.equals(counter.getId().getTag("uri")))
|
||||||
|
.mapToDouble(Counter::count)
|
||||||
|
.sum();
|
||||||
|
log.info("Request count: {}", count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<EndpointCount> getEndpointCounts(String method) {
|
||||||
|
log.info("Getting endpoint counts for method: {}", method);
|
||||||
|
Map<String, Double> counts = new HashMap<>();
|
||||||
|
meterRegistry
|
||||||
|
.find("http.requests")
|
||||||
|
.tag("method", method)
|
||||||
|
.counters()
|
||||||
|
.forEach(
|
||||||
|
counter -> {
|
||||||
|
String uri = counter.getId().getTag("uri");
|
||||||
|
counts.merge(uri, counter.count(), Double::sum);
|
||||||
|
});
|
||||||
|
|
||||||
|
List<EndpointCount> result =
|
||||||
|
counts.entrySet().stream()
|
||||||
|
.map(entry -> new EndpointCount(entry.getKey(), entry.getValue()))
|
||||||
|
.sorted(Comparator.comparing(EndpointCount::getCount).reversed())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
log.info("Found {} endpoints with counts", result.size());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getUniqueUserCount(String method, Optional<String> endpoint) {
|
||||||
|
log.info(
|
||||||
|
"Getting unique user count for method: {}, endpoint: {}",
|
||||||
|
method,
|
||||||
|
endpoint.orElse("all"));
|
||||||
|
Set<String> uniqueUsers = new HashSet<>();
|
||||||
|
meterRegistry.find("http.requests").tag("method", method).counters().stream()
|
||||||
|
.filter(
|
||||||
|
counter ->
|
||||||
|
!endpoint.isPresent()
|
||||||
|
|| endpoint.get().equals(counter.getId().getTag("uri")))
|
||||||
|
.forEach(
|
||||||
|
counter -> {
|
||||||
|
String session = counter.getId().getTag("session");
|
||||||
|
if (session != null) {
|
||||||
|
uniqueUsers.add(session);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
log.info("Unique user count: {}", uniqueUsers.size());
|
||||||
|
return uniqueUsers.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<EndpointCount> getUniqueUserCounts(String method) {
|
||||||
|
log.info("Getting unique user counts for method: {}", method);
|
||||||
|
Map<String, Set<String>> uniqueUsers = new HashMap<>();
|
||||||
|
|
||||||
|
meterRegistry
|
||||||
|
.find("http.requests")
|
||||||
|
.tag("method", method)
|
||||||
|
.counters()
|
||||||
|
.forEach(
|
||||||
|
counter -> {
|
||||||
|
String uri = counter.getId().getTag("uri");
|
||||||
|
String session = counter.getId().getTag("session");
|
||||||
|
if (uri != null && session != null) {
|
||||||
|
uniqueUsers.computeIfAbsent(uri, k -> new HashSet<>()).add(session);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
List<EndpointCount> result =
|
||||||
|
uniqueUsers.entrySet().stream()
|
||||||
|
.map(entry -> new EndpointCount(entry.getKey(), entry.getValue().size()))
|
||||||
|
.sorted(Comparator.comparing(EndpointCount::getCount).reversed())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
log.info("Found {} endpoints with unique user counts", result.size());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EndpointCount {
|
||||||
private String endpoint;
|
private String endpoint;
|
||||||
private double count;
|
private double count;
|
||||||
|
|
||||||
@@ -180,86 +321,6 @@ public class MetricsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/requests")
|
|
||||||
@Operation(
|
|
||||||
summary = "POST request count",
|
|
||||||
description =
|
|
||||||
"This endpoint returns the total count of POST requests or the count of POST requests for a specific endpoint.")
|
|
||||||
public ResponseEntity<?> getTotalRequests(
|
|
||||||
@RequestParam(required = false, name = "endpoint") @Parameter(description = "endpoint")
|
|
||||||
Optional<String> endpoint) {
|
|
||||||
if (!metricsEnabled) {
|
|
||||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
double count = 0.0;
|
|
||||||
|
|
||||||
for (Meter meter : meterRegistry.getMeters()) {
|
|
||||||
if (meter.getId().getName().equals("http.requests")) {
|
|
||||||
String method = meter.getId().getTag("method");
|
|
||||||
if (method != null && "POST".equals(method)) {
|
|
||||||
if (endpoint.isPresent() && !endpoint.get().isBlank()) {
|
|
||||||
if (!endpoint.get().startsWith("/")) {
|
|
||||||
endpoint = Optional.of("/" + endpoint.get());
|
|
||||||
}
|
|
||||||
if (endpoint.get().equals(meter.getId().getTag("uri"))) {
|
|
||||||
if (meter instanceof Counter) {
|
|
||||||
count += ((Counter) meter).count();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (meter instanceof Counter) {
|
|
||||||
count += ((Counter) meter).count();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ResponseEntity.ok(count);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return ResponseEntity.ok(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/requests/all")
|
|
||||||
@Operation(
|
|
||||||
summary = "POST requests count for all endpoints",
|
|
||||||
description = "This endpoint returns the count of POST requests for each endpoint.")
|
|
||||||
public ResponseEntity<?> getAllPostRequests() {
|
|
||||||
if (!metricsEnabled) {
|
|
||||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("This endpoint is disabled.");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Map<String, Double> counts = new HashMap<>();
|
|
||||||
|
|
||||||
for (Meter meter : meterRegistry.getMeters()) {
|
|
||||||
if (meter.getId().getName().equals("http.requests")) {
|
|
||||||
String method = meter.getId().getTag("method");
|
|
||||||
if (method != null && "POST".equals(method)) {
|
|
||||||
String uri = meter.getId().getTag("uri");
|
|
||||||
if (uri != null) {
|
|
||||||
double currentCount = counts.getOrDefault(uri, 0.0);
|
|
||||||
if (meter instanceof Counter) {
|
|
||||||
currentCount += ((Counter) meter).count();
|
|
||||||
}
|
|
||||||
counts.put(uri, currentCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<EndpointCount> results =
|
|
||||||
counts.entrySet().stream()
|
|
||||||
.map(entry -> new EndpointCount(entry.getKey(), entry.getValue()))
|
|
||||||
.sorted(Comparator.comparing(EndpointCount::getCount).reversed())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
return ResponseEntity.ok(results);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/uptime")
|
@GetMapping("/uptime")
|
||||||
public ResponseEntity<?> getUptime() {
|
public ResponseEntity<?> getUptime() {
|
||||||
if (!metricsEnabled) {
|
if (!metricsEnabled) {
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.PropertySource;
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
import stirling.software.SPDF.config.YamlPropertySourceFactory;
|
import stirling.software.SPDF.config.YamlPropertySourceFactory;
|
||||||
import stirling.software.SPDF.model.provider.GithubProvider;
|
import stirling.software.SPDF.model.provider.GithubProvider;
|
||||||
import stirling.software.SPDF.model.provider.GoogleProvider;
|
import stirling.software.SPDF.model.provider.GoogleProvider;
|
||||||
@@ -21,225 +23,56 @@ import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
|||||||
@Configuration
|
@Configuration
|
||||||
@ConfigurationProperties(prefix = "")
|
@ConfigurationProperties(prefix = "")
|
||||||
@PropertySource(value = "file:./configs/settings.yml", factory = YamlPropertySourceFactory.class)
|
@PropertySource(value = "file:./configs/settings.yml", factory = YamlPropertySourceFactory.class)
|
||||||
|
@Data
|
||||||
public class ApplicationProperties {
|
public class ApplicationProperties {
|
||||||
private Security security;
|
|
||||||
private System system;
|
private Legal legal = new Legal();
|
||||||
private Ui ui;
|
private Security security = new Security();
|
||||||
private Endpoints endpoints;
|
private System system = new System();
|
||||||
private Metrics metrics;
|
private Ui ui = new Ui();
|
||||||
private AutomaticallyGenerated automaticallyGenerated;
|
private Endpoints endpoints = new Endpoints();
|
||||||
private AutoPipeline autoPipeline;
|
private Metrics metrics = new Metrics();
|
||||||
|
private AutomaticallyGenerated automaticallyGenerated = new AutomaticallyGenerated();
|
||||||
|
private EnterpriseEdition enterpriseEdition = new EnterpriseEdition();
|
||||||
|
private AutoPipeline autoPipeline = new AutoPipeline();
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ApplicationProperties.class);
|
private static final Logger logger = LoggerFactory.getLogger(ApplicationProperties.class);
|
||||||
|
|
||||||
public AutoPipeline getAutoPipeline() {
|
@Data
|
||||||
return autoPipeline != null ? autoPipeline : new AutoPipeline();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAutoPipeline(AutoPipeline autoPipeline) {
|
|
||||||
this.autoPipeline = autoPipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Security getSecurity() {
|
|
||||||
return security != null ? security : new Security();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSecurity(Security security) {
|
|
||||||
this.security = security;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System getSystem() {
|
|
||||||
return system != null ? system : new System();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSystem(System system) {
|
|
||||||
this.system = system;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Ui getUi() {
|
|
||||||
return ui != null ? ui : new Ui();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUi(Ui ui) {
|
|
||||||
this.ui = ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Endpoints getEndpoints() {
|
|
||||||
return endpoints != null ? endpoints : new Endpoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEndpoints(Endpoints endpoints) {
|
|
||||||
this.endpoints = endpoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Metrics getMetrics() {
|
|
||||||
return metrics != null ? metrics : new Metrics();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMetrics(Metrics metrics) {
|
|
||||||
this.metrics = metrics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AutomaticallyGenerated getAutomaticallyGenerated() {
|
|
||||||
return automaticallyGenerated != null
|
|
||||||
? automaticallyGenerated
|
|
||||||
: new AutomaticallyGenerated();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAutomaticallyGenerated(AutomaticallyGenerated automaticallyGenerated) {
|
|
||||||
this.automaticallyGenerated = automaticallyGenerated;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "ApplicationProperties [security="
|
|
||||||
+ security
|
|
||||||
+ ", system="
|
|
||||||
+ system
|
|
||||||
+ ", ui="
|
|
||||||
+ ui
|
|
||||||
+ ", endpoints="
|
|
||||||
+ endpoints
|
|
||||||
+ ", metrics="
|
|
||||||
+ metrics
|
|
||||||
+ ", automaticallyGenerated="
|
|
||||||
+ automaticallyGenerated
|
|
||||||
+ ", autoPipeline="
|
|
||||||
+ autoPipeline
|
|
||||||
+ "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AutoPipeline {
|
public static class AutoPipeline {
|
||||||
private String outputFolder;
|
private String outputFolder;
|
||||||
|
|
||||||
public String getOutputFolder() {
|
|
||||||
return outputFolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOutputFolder(String outputFolder) {
|
|
||||||
this.outputFolder = outputFolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "AutoPipeline [outputFolder=" + outputFolder + "]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Legal {
|
||||||
|
private String termsAndConditions;
|
||||||
|
private String privacyPolicy;
|
||||||
|
private String accessibilityStatement;
|
||||||
|
private String cookiePolicy;
|
||||||
|
private String impressum;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
public static class Security {
|
public static class Security {
|
||||||
private Boolean enableLogin;
|
private Boolean enableLogin;
|
||||||
private Boolean csrfDisabled;
|
private Boolean csrfDisabled;
|
||||||
private InitialLogin initialLogin;
|
private InitialLogin initialLogin = new InitialLogin();
|
||||||
private OAUTH2 oauth2;
|
private OAUTH2 oauth2 = new OAUTH2();
|
||||||
private int loginAttemptCount;
|
private int loginAttemptCount;
|
||||||
private long loginResetTimeMinutes;
|
private long loginResetTimeMinutes;
|
||||||
private String loginMethod = "all";
|
private String loginMethod = "all";
|
||||||
|
|
||||||
public String getLoginMethod() {
|
@Data
|
||||||
return loginMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoginMethod(String loginMethod) {
|
|
||||||
this.loginMethod = loginMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLoginAttemptCount() {
|
|
||||||
return loginAttemptCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoginAttemptCount(int loginAttemptCount) {
|
|
||||||
this.loginAttemptCount = loginAttemptCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLoginResetTimeMinutes() {
|
|
||||||
return loginResetTimeMinutes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoginResetTimeMinutes(long loginResetTimeMinutes) {
|
|
||||||
this.loginResetTimeMinutes = loginResetTimeMinutes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InitialLogin getInitialLogin() {
|
|
||||||
return initialLogin != null ? initialLogin : new InitialLogin();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInitialLogin(InitialLogin initialLogin) {
|
|
||||||
this.initialLogin = initialLogin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OAUTH2 getOAUTH2() {
|
|
||||||
return oauth2 != null ? oauth2 : new OAUTH2();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOAUTH2(OAUTH2 oauth2) {
|
|
||||||
this.oauth2 = oauth2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getEnableLogin() {
|
|
||||||
return enableLogin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnableLogin(Boolean enableLogin) {
|
|
||||||
this.enableLogin = enableLogin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getCsrfDisabled() {
|
|
||||||
return csrfDisabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCsrfDisabled(Boolean csrfDisabled) {
|
|
||||||
this.csrfDisabled = csrfDisabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Security [enableLogin="
|
|
||||||
+ enableLogin
|
|
||||||
+ ", oauth2="
|
|
||||||
+ oauth2
|
|
||||||
+ ", initialLogin="
|
|
||||||
+ initialLogin
|
|
||||||
+ ", csrfDisabled="
|
|
||||||
+ csrfDisabled
|
|
||||||
+ ", loginMethod="
|
|
||||||
+ loginMethod
|
|
||||||
+ "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InitialLogin {
|
public static class InitialLogin {
|
||||||
private String username;
|
private String username;
|
||||||
private String password;
|
@ToString.Exclude private String password;
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "InitialLogin [username="
|
|
||||||
+ username
|
|
||||||
+ ", password="
|
|
||||||
+ (password != null && !password.isEmpty() ? "MASKED" : "NULL")
|
|
||||||
+ "]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
public static class OAUTH2 {
|
public static class OAUTH2 {
|
||||||
private Boolean enabled = false;
|
private Boolean enabled = false;
|
||||||
private String issuer;
|
private String issuer;
|
||||||
private String clientId;
|
private String clientId;
|
||||||
private String clientSecret;
|
@ToString.Exclude private String clientSecret;
|
||||||
private Boolean autoCreateUser = false;
|
private Boolean autoCreateUser = false;
|
||||||
private Boolean blockRegistration = false;
|
private Boolean blockRegistration = false;
|
||||||
private String useAsUsername;
|
private String useAsUsername;
|
||||||
@@ -247,74 +80,6 @@ public class ApplicationProperties {
|
|||||||
private String provider;
|
private String provider;
|
||||||
private Client client = new Client();
|
private Client client = new Client();
|
||||||
|
|
||||||
public Boolean getEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnabled(Boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIssuer() {
|
|
||||||
return issuer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIssuer(String issuer) {
|
|
||||||
this.issuer = issuer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientId() {
|
|
||||||
return clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClientId(String clientId) {
|
|
||||||
this.clientId = clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClientSecret() {
|
|
||||||
return clientSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClientSecret(String clientSecret) {
|
|
||||||
this.clientSecret = clientSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getAutoCreateUser() {
|
|
||||||
return autoCreateUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAutoCreateUser(Boolean autoCreateUser) {
|
|
||||||
this.autoCreateUser = autoCreateUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getBlockRegistration() {
|
|
||||||
return blockRegistration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBlockRegistration(Boolean blockRegistration) {
|
|
||||||
this.blockRegistration = blockRegistration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUseAsUsername() {
|
|
||||||
return useAsUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUseAsUsername(String useAsUsername) {
|
|
||||||
this.useAsUsername = useAsUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProvider() {
|
|
||||||
return provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProvider(String provider) {
|
|
||||||
this.provider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<String> getScopes() {
|
|
||||||
return scopes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setScopes(String scopes) {
|
public void setScopes(String scopes) {
|
||||||
List<String> scopesList =
|
List<String> scopesList =
|
||||||
Arrays.stream(scopes.split(","))
|
Arrays.stream(scopes.split(","))
|
||||||
@@ -323,26 +88,12 @@ public class ApplicationProperties {
|
|||||||
this.scopes.addAll(scopesList);
|
this.scopes.addAll(scopesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Client getClient() {
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClient(Client client) {
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isValid(String value, String name) {
|
protected boolean isValid(String value, String name) {
|
||||||
if (value != null && !value.trim().isEmpty()) {
|
return value != null && !value.trim().isEmpty();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isValid(Collection<String> value, String name) {
|
protected boolean isValid(Collection<String> value, String name) {
|
||||||
if (value != null && !value.isEmpty()) {
|
return value != null && !value.isEmpty();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSettingsValid() {
|
public boolean isSettingsValid() {
|
||||||
@@ -353,31 +104,7 @@ public class ApplicationProperties {
|
|||||||
&& isValid(this.getUseAsUsername(), "useAsUsername");
|
&& isValid(this.getUseAsUsername(), "useAsUsername");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Data
|
||||||
public String toString() {
|
|
||||||
return "OAUTH2 [enabled="
|
|
||||||
+ enabled
|
|
||||||
+ ", issuer="
|
|
||||||
+ issuer
|
|
||||||
+ ", clientId="
|
|
||||||
+ clientId
|
|
||||||
+ ", clientSecret="
|
|
||||||
+ (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL")
|
|
||||||
+ ", autoCreateUser="
|
|
||||||
+ autoCreateUser
|
|
||||||
+ ", blockRegistration="
|
|
||||||
+ blockRegistration
|
|
||||||
+ ", useAsUsername="
|
|
||||||
+ useAsUsername
|
|
||||||
+ ", provider="
|
|
||||||
+ provider
|
|
||||||
+ ", client="
|
|
||||||
+ client
|
|
||||||
+ ", scopes="
|
|
||||||
+ scopes
|
|
||||||
+ "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Client {
|
public static class Client {
|
||||||
private GoogleProvider google = new GoogleProvider();
|
private GoogleProvider google = new GoogleProvider();
|
||||||
private GithubProvider github = new GithubProvider();
|
private GithubProvider github = new GithubProvider();
|
||||||
@@ -392,50 +119,15 @@ public class ApplicationProperties {
|
|||||||
case "keycloak":
|
case "keycloak":
|
||||||
return getKeycloak();
|
return getKeycloak();
|
||||||
default:
|
default:
|
||||||
break;
|
throw new UnsupportedProviderException(
|
||||||
|
"Logout from the provider is not supported? Report it at https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
||||||
}
|
}
|
||||||
throw new UnsupportedProviderException(
|
|
||||||
"Logout from the provider is not supported? Report it at https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
|
||||||
}
|
|
||||||
|
|
||||||
public GoogleProvider getGoogle() {
|
|
||||||
return google;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGoogle(GoogleProvider google) {
|
|
||||||
this.google = google;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GithubProvider getGithub() {
|
|
||||||
return github;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGithub(GithubProvider github) {
|
|
||||||
this.github = github;
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeycloakProvider getKeycloak() {
|
|
||||||
return keycloak;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKeycloak(KeycloakProvider keycloak) {
|
|
||||||
this.keycloak = keycloak;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Client [google="
|
|
||||||
+ google
|
|
||||||
+ ", github="
|
|
||||||
+ github
|
|
||||||
+ ", keycloak="
|
|
||||||
+ keycloak
|
|
||||||
+ "]";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
public static class System {
|
public static class System {
|
||||||
private String defaultLocale;
|
private String defaultLocale;
|
||||||
private Boolean googlevisibility;
|
private Boolean googlevisibility;
|
||||||
@@ -443,184 +135,67 @@ public class ApplicationProperties {
|
|||||||
private Boolean showUpdateOnlyAdmin;
|
private Boolean showUpdateOnlyAdmin;
|
||||||
private boolean customHTMLFiles;
|
private boolean customHTMLFiles;
|
||||||
private String tessdataDir;
|
private String tessdataDir;
|
||||||
|
|
||||||
public String getTessdataDir() {
|
|
||||||
return tessdataDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTessdataDir(String tessdataDir) {
|
|
||||||
this.tessdataDir = tessdataDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCustomHTMLFiles() {
|
|
||||||
return customHTMLFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCustomHTMLFiles(boolean customHTMLFiles) {
|
|
||||||
this.customHTMLFiles = customHTMLFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getShowUpdateOnlyAdmin() {
|
|
||||||
return showUpdateOnlyAdmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShowUpdateOnlyAdmin(boolean showUpdateOnlyAdmin) {
|
|
||||||
this.showUpdateOnlyAdmin = showUpdateOnlyAdmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getShowUpdate() {
|
|
||||||
return showUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShowUpdate(boolean showUpdate) {
|
|
||||||
this.showUpdate = showUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean enableAlphaFunctionality;
|
private Boolean enableAlphaFunctionality;
|
||||||
|
|
||||||
public Boolean getEnableAlphaFunctionality() {
|
|
||||||
return enableAlphaFunctionality;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnableAlphaFunctionality(Boolean enableAlphaFunctionality) {
|
|
||||||
this.enableAlphaFunctionality = enableAlphaFunctionality;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDefaultLocale() {
|
|
||||||
return defaultLocale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultLocale(String defaultLocale) {
|
|
||||||
this.defaultLocale = defaultLocale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getGooglevisibility() {
|
|
||||||
return googlevisibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGooglevisibility(Boolean googlevisibility) {
|
|
||||||
this.googlevisibility = googlevisibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "System [defaultLocale="
|
|
||||||
+ defaultLocale
|
|
||||||
+ ", googlevisibility="
|
|
||||||
+ googlevisibility
|
|
||||||
+ ", enableAlphaFunctionality="
|
|
||||||
+ enableAlphaFunctionality
|
|
||||||
+ ", showUpdate="
|
|
||||||
+ showUpdate
|
|
||||||
+ ", showUpdateOnlyAdmin="
|
|
||||||
+ showUpdateOnlyAdmin
|
|
||||||
+ "]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
public static class Ui {
|
public static class Ui {
|
||||||
private String appName;
|
private String appName;
|
||||||
private String homeDescription;
|
private String homeDescription;
|
||||||
private String appNameNavbar;
|
private String appNameNavbar;
|
||||||
|
|
||||||
public String getAppName() {
|
public String getAppName() {
|
||||||
if (appName != null && appName.trim().length() == 0) return null;
|
return appName != null && appName.trim().length() > 0 ? appName : null;
|
||||||
return appName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAppName(String appName) {
|
|
||||||
this.appName = appName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHomeDescription() {
|
public String getHomeDescription() {
|
||||||
if (homeDescription != null && homeDescription.trim().length() == 0) return null;
|
return homeDescription != null && homeDescription.trim().length() > 0
|
||||||
return homeDescription;
|
? homeDescription
|
||||||
}
|
: null;
|
||||||
|
|
||||||
public void setHomeDescription(String homeDescription) {
|
|
||||||
this.homeDescription = homeDescription;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAppNameNavbar() {
|
public String getAppNameNavbar() {
|
||||||
if (appNameNavbar != null && appNameNavbar.trim().length() == 0) return null;
|
return appNameNavbar != null && appNameNavbar.trim().length() > 0
|
||||||
return appNameNavbar;
|
? appNameNavbar
|
||||||
}
|
: null;
|
||||||
|
|
||||||
public void setAppNameNavbar(String appNameNavbar) {
|
|
||||||
this.appNameNavbar = appNameNavbar;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "UserInterface [appName="
|
|
||||||
+ appName
|
|
||||||
+ ", homeDescription="
|
|
||||||
+ homeDescription
|
|
||||||
+ ", appNameNavbar="
|
|
||||||
+ appNameNavbar
|
|
||||||
+ "]";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
public static class Endpoints {
|
public static class Endpoints {
|
||||||
private List<String> toRemove;
|
private List<String> toRemove;
|
||||||
private List<String> groupsToRemove;
|
private List<String> groupsToRemove;
|
||||||
|
|
||||||
public List<String> getToRemove() {
|
|
||||||
return toRemove;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setToRemove(List<String> toRemove) {
|
|
||||||
this.toRemove = toRemove;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getGroupsToRemove() {
|
|
||||||
return groupsToRemove;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGroupsToRemove(List<String> groupsToRemove) {
|
|
||||||
this.groupsToRemove = groupsToRemove;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Endpoints [toRemove=" + toRemove + ", groupsToRemove=" + groupsToRemove + "]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
public static class Metrics {
|
public static class Metrics {
|
||||||
private Boolean enabled;
|
private Boolean enabled;
|
||||||
|
|
||||||
public Boolean getEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnabled(Boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Metrics [enabled=" + enabled + "]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
public static class AutomaticallyGenerated {
|
public static class AutomaticallyGenerated {
|
||||||
private String key;
|
@ToString.Exclude private String key;
|
||||||
|
}
|
||||||
|
|
||||||
public String getKey() {
|
@Data
|
||||||
return key;
|
public static class EnterpriseEdition {
|
||||||
}
|
@ToString.Exclude private String key;
|
||||||
|
private CustomMetadata customMetadata = new CustomMetadata();
|
||||||
|
|
||||||
public void setKey(String key) {
|
@Data
|
||||||
this.key = key;
|
public static class CustomMetadata {
|
||||||
}
|
private boolean autoUpdateMetadata;
|
||||||
|
private String author;
|
||||||
|
private String creator;
|
||||||
|
private String producer;
|
||||||
|
|
||||||
@Override
|
public String getCreator() {
|
||||||
public String toString() {
|
return creator == null || creator.trim().isEmpty() ? "Stirling-PDF" : creator;
|
||||||
return "AutomaticallyGenerated [key="
|
}
|
||||||
+ (key != null && !key.isEmpty() ? "MASKED" : "NULL")
|
|
||||||
+ "]";
|
public String getProducer() {
|
||||||
|
return producer == null || producer.trim().isEmpty() ? "Stirling-PDF" : producer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class PDFWithPageSize extends PDFFile {
|
|||||||
|
|
||||||
@Schema(
|
@Schema(
|
||||||
description =
|
description =
|
||||||
"The scale of pages in the output PDF. Acceptable values are A0-A6, LETTER, LEGAL.",
|
"The scale of pages in the output PDF. Acceptable values are A0-A6, LETTER, LEGAL, KEEP.",
|
||||||
allowableValues = {"A0", "A1", "A2", "A3", "A4", "A5", "A6", "LETTER", "LEGAL"})
|
allowableValues = {"A0", "A1", "A2", "A3", "A4", "A5", "A6", "LETTER", "LEGAL", "KEEP"})
|
||||||
private String pageSize;
|
private String pageSize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ public interface UserRepository extends JpaRepository<User, Long> {
|
|||||||
@Query("FROM User u LEFT JOIN FETCH u.settings where upper(u.username) = upper(:username)")
|
@Query("FROM User u LEFT JOIN FETCH u.settings where upper(u.username) = upper(:username)")
|
||||||
Optional<User> findByUsernameIgnoreCaseWithSettings(@Param("username") String username);
|
Optional<User> findByUsernameIgnoreCaseWithSettings(@Param("username") String username);
|
||||||
|
|
||||||
|
|
||||||
Optional<User> findByUsername(String username);
|
Optional<User> findByUsername(String username);
|
||||||
|
|
||||||
Optional<User> findByApiKey(String apiKey);
|
Optional<User> findByApiKey(String apiKey);
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package stirling.software.SPDF.service;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.apache.pdfbox.Loader;
|
||||||
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.config.PdfMetadataService;
|
||||||
|
import stirling.software.SPDF.model.PdfMetadata;
|
||||||
|
import stirling.software.SPDF.model.api.PDFFile;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CustomPDDocumentFactory {
|
||||||
|
|
||||||
|
private final PdfMetadataService pdfMetadataService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CustomPDDocumentFactory(PdfMetadataService pdfMetadataService) {
|
||||||
|
this.pdfMetadataService = pdfMetadataService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PDDocument createNewDocument() throws IOException {
|
||||||
|
PDDocument document = new PDDocument();
|
||||||
|
pdfMetadataService.setMetadataToPdf(document, PdfMetadata.builder().build(), true);
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PDDocument createNewDocumentBasedOnOldDocument(PDDocument oldDocument)
|
||||||
|
throws IOException {
|
||||||
|
PDDocument document = new PDDocument();
|
||||||
|
pdfMetadataService.setMetadataToPdf(
|
||||||
|
document, pdfMetadataService.extractMetadataFromPdf(oldDocument), true);
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] loadToBytes(File file) throws IOException {
|
||||||
|
PDDocument document = load(file);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
document.save(baos);
|
||||||
|
// Close the document
|
||||||
|
document.close();
|
||||||
|
return baos.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] loadToBytes(byte[] bytes) throws IOException {
|
||||||
|
PDDocument document = load(bytes);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
document.save(baos);
|
||||||
|
// Close the document
|
||||||
|
document.close();
|
||||||
|
return baos.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if loading from a file, assume the file has been made with Stirling-PDF
|
||||||
|
public PDDocument load(File file) throws IOException {
|
||||||
|
PDDocument document = Loader.loadPDF(file);
|
||||||
|
pdfMetadataService.setMetadataToPdf(document, PdfMetadata.builder().build(), true);
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PDDocument load(InputStream input) throws IOException {
|
||||||
|
return load(input.readAllBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PDDocument load(byte[] input) throws IOException {
|
||||||
|
PDDocument document = Loader.loadPDF(input);
|
||||||
|
pdfMetadataService.setDefaultMetadata(document);
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PDDocument load(PDFFile pdfFile) throws IOException {
|
||||||
|
return load(pdfFile.getFileInput());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PDDocument load(MultipartFile pdfFile) throws IOException {
|
||||||
|
return load(pdfFile.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PDDocument load(String path) throws IOException {
|
||||||
|
return load(new File(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PDDocument load(MultipartFile fileInput, String password) throws IOException {
|
||||||
|
return load(fileInput.getBytes(), password);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PDDocument load(byte[] bytes, String password) throws IOException {
|
||||||
|
PDDocument document = Loader.loadPDF(bytes, password);
|
||||||
|
pdfMetadataService.setDefaultMetadata(document);
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add other load methods as needed, following the same pattern
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import java.awt.image.RenderedImage;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
@@ -37,7 +36,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.PdfMetadata;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
|
|
||||||
public class PdfUtils {
|
public class PdfUtils {
|
||||||
|
|
||||||
@@ -383,9 +382,13 @@ public class PdfUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] imageToPdf(
|
public static byte[] imageToPdf(
|
||||||
MultipartFile[] files, String fitOption, boolean autoRotate, String colorType)
|
MultipartFile[] files,
|
||||||
|
String fitOption,
|
||||||
|
boolean autoRotate,
|
||||||
|
String colorType,
|
||||||
|
CustomPDDocumentFactory pdfDocumentFactory)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
try (PDDocument doc = new PDDocument()) {
|
try (PDDocument doc = pdfDocumentFactory.createNewDocument()) {
|
||||||
for (MultipartFile file : files) {
|
for (MultipartFile file : files) {
|
||||||
String contentType = file.getContentType();
|
String contentType = file.getContentType();
|
||||||
String originalFilename = Filenames.toSimpleFileName(file.getOriginalFilename());
|
String originalFilename = Filenames.toSimpleFileName(file.getOriginalFilename());
|
||||||
@@ -473,10 +476,15 @@ public class PdfUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] overlayImage(
|
public static byte[] overlayImage(
|
||||||
byte[] pdfBytes, byte[] imageBytes, float x, float y, boolean everyPage)
|
CustomPDDocumentFactory pdfDocumentFactory,
|
||||||
|
byte[] pdfBytes,
|
||||||
|
byte[] imageBytes,
|
||||||
|
float x,
|
||||||
|
float y,
|
||||||
|
boolean everyPage)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
PDDocument document = Loader.loadPDF(pdfBytes);
|
PDDocument document = pdfDocumentFactory.load(pdfBytes);
|
||||||
|
|
||||||
// Get the first page of the PDF
|
// Get the first page of the PDF
|
||||||
int pages = document.getNumberOfPages();
|
int pages = document.getNumberOfPages();
|
||||||
@@ -506,30 +514,6 @@ public class PdfUtils {
|
|||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PdfMetadata extractMetadataFromPdf(PDDocument pdf) {
|
|
||||||
return PdfMetadata.builder()
|
|
||||||
.author(pdf.getDocumentInformation().getAuthor())
|
|
||||||
.producer(pdf.getDocumentInformation().getProducer())
|
|
||||||
.title(pdf.getDocumentInformation().getTitle())
|
|
||||||
.creator(pdf.getDocumentInformation().getCreator())
|
|
||||||
.subject(pdf.getDocumentInformation().getSubject())
|
|
||||||
.keywords(pdf.getDocumentInformation().getKeywords())
|
|
||||||
.creationDate(pdf.getDocumentInformation().getCreationDate())
|
|
||||||
.modificationDate(pdf.getDocumentInformation().getModificationDate())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setMetadataToPdf(PDDocument pdf, PdfMetadata pdfMetadata) {
|
|
||||||
pdf.getDocumentInformation().setAuthor(pdfMetadata.getAuthor());
|
|
||||||
pdf.getDocumentInformation().setProducer(pdfMetadata.getProducer());
|
|
||||||
pdf.getDocumentInformation().setTitle(pdfMetadata.getTitle());
|
|
||||||
pdf.getDocumentInformation().setCreator(pdfMetadata.getCreator());
|
|
||||||
pdf.getDocumentInformation().setSubject(pdfMetadata.getSubject());
|
|
||||||
pdf.getDocumentInformation().setKeywords(pdfMetadata.getKeywords());
|
|
||||||
pdf.getDocumentInformation().setCreationDate(pdfMetadata.getCreationDate());
|
|
||||||
pdf.getDocumentInformation().setModificationDate(Calendar.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Key for storing the dimensions of a rendered image in a map. */
|
/** Key for storing the dimensions of a rendered image in a map. */
|
||||||
private record PdfRenderSettingsKey(float mediaBoxWidth, float mediaBoxHeight, int rotation) {}
|
private record PdfRenderSettingsKey(float mediaBoxWidth, float mediaBoxHeight, int rotation) {}
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,7 @@ public class RequestUriUtils {
|
|||||||
|
|
||||||
public static boolean isStaticResource(String requestURI) {
|
public static boolean isStaticResource(String requestURI) {
|
||||||
|
|
||||||
return requestURI.startsWith("/css/")
|
return isStaticResource("", requestURI);
|
||||||
|| requestURI.startsWith("/fonts/")
|
|
||||||
|| requestURI.startsWith("/js/")
|
|
||||||
|| requestURI.startsWith("/images/")
|
|
||||||
|| requestURI.startsWith("/public/")
|
|
||||||
|| requestURI.startsWith("/pdfjs/")
|
|
||||||
|| requestURI.startsWith("/pdfjs-legacy/")
|
|
||||||
|| requestURI.endsWith(".svg")
|
|
||||||
|| requestURI.endsWith(".webmanifest")
|
|
||||||
|| requestURI.startsWith("/api/v1/info/status");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isStaticResource(String contextPath, String requestURI) {
|
public static boolean isStaticResource(String contextPath, String requestURI) {
|
||||||
@@ -21,11 +12,37 @@ public class RequestUriUtils {
|
|||||||
return requestURI.startsWith(contextPath + "/css/")
|
return requestURI.startsWith(contextPath + "/css/")
|
||||||
|| requestURI.startsWith(contextPath + "/fonts/")
|
|| requestURI.startsWith(contextPath + "/fonts/")
|
||||||
|| requestURI.startsWith(contextPath + "/js/")
|
|| requestURI.startsWith(contextPath + "/js/")
|
||||||
|
|| requestURI.endsWith(contextPath + "robots.txt")
|
||||||
|| requestURI.startsWith(contextPath + "/images/")
|
|| requestURI.startsWith(contextPath + "/images/")
|
||||||
|| requestURI.startsWith(contextPath + "/public/")
|
|| requestURI.startsWith(contextPath + "/public/")
|
||||||
|| requestURI.startsWith(contextPath + "/pdfjs/")
|
|| requestURI.startsWith(contextPath + "/pdfjs/")
|
||||||
|
|| requestURI.startsWith(contextPath + "/login")
|
||||||
|| requestURI.endsWith(".svg")
|
|| requestURI.endsWith(".svg")
|
||||||
|
|| requestURI.endsWith(".png")
|
||||||
|
|| requestURI.endsWith(".ico")
|
||||||
|| requestURI.endsWith(".webmanifest")
|
|| requestURI.endsWith(".webmanifest")
|
||||||
|| requestURI.startsWith(contextPath + "/api/v1/info/status");
|
|| requestURI.startsWith(contextPath + "/api/v1/info/status");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isTrackableResource(String requestURI) {
|
||||||
|
return isTrackableResource("", requestURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isTrackableResource(String contextPath, String requestURI) {
|
||||||
|
return !(requestURI.startsWith("/js")
|
||||||
|
|| requestURI.startsWith("/v1/api-docs")
|
||||||
|
|| requestURI.endsWith("robots.txt")
|
||||||
|
|| requestURI.startsWith("/images")
|
||||||
|
|| requestURI.endsWith(".png")
|
||||||
|
|| requestURI.endsWith(".ico")
|
||||||
|
|| requestURI.endsWith(".css")
|
||||||
|
|| requestURI.endsWith(".map")
|
||||||
|
|| requestURI.endsWith(".svg")
|
||||||
|
|| requestURI.endsWith(".js")
|
||||||
|
|| requestURI.contains("swagger")
|
||||||
|
|| requestURI.startsWith("/api/v1/info")
|
||||||
|
|| requestURI.startsWith("/site.webmanifest")
|
||||||
|
|| requestURI.startsWith("/fonts")
|
||||||
|
|| requestURI.startsWith("/pdfjs"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=لون
|
|||||||
sponsor=راعٍ
|
sponsor=راعٍ
|
||||||
info=معلومات
|
info=معلومات
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=إرسال
|
|||||||
scalePages.title=ضبط مقياس الصفحة
|
scalePages.title=ضبط مقياس الصفحة
|
||||||
scalePages.header=ضبط مقياس الصفحة
|
scalePages.header=ضبط مقياس الصفحة
|
||||||
scalePages.pageSize=حجم صفحة المستند.
|
scalePages.pageSize=حجم صفحة المستند.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=مستوى التكبير (الاقتصاص) للصفحة.
|
scalePages.scaleFactor=مستوى التكبير (الاقتصاص) للصفحة.
|
||||||
scalePages.submit=إرسال
|
scalePages.submit=إرسال
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Цвят
|
|||||||
sponsor=Спонсор
|
sponsor=Спонсор
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Подайте
|
|||||||
scalePages.title=Коригиране на мащаба на страницата
|
scalePages.title=Коригиране на мащаба на страницата
|
||||||
scalePages.header=Коригиране на мащаба на страницата
|
scalePages.header=Коригиране на мащаба на страницата
|
||||||
scalePages.pageSize=Размер на страница от документа.
|
scalePages.pageSize=Размер на страница от документа.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Ниво на мащабиране (изрязване) на страница.
|
scalePages.scaleFactor=Ниво на мащабиране (изрязване) на страница.
|
||||||
scalePages.submit=Подайте
|
scalePages.submit=Подайте
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Color
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Submit
|
|||||||
scalePages.title=Adjust page-scale
|
scalePages.title=Adjust page-scale
|
||||||
scalePages.header=Adjust page-scale
|
scalePages.header=Adjust page-scale
|
||||||
scalePages.pageSize=Size of a page of the document.
|
scalePages.pageSize=Size of a page of the document.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Zoom level (crop) of a page.
|
scalePages.scaleFactor=Zoom level (crop) of a page.
|
||||||
scalePages.submit=Submit
|
scalePages.submit=Submit
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Barva
|
|||||||
sponsor=Sponzor
|
sponsor=Sponzor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Odeslat
|
|||||||
scalePages.title=Upravit měřítko stránky
|
scalePages.title=Upravit měřítko stránky
|
||||||
scalePages.header=Upravit měřítko stránky
|
scalePages.header=Upravit měřítko stránky
|
||||||
scalePages.pageSize=Velikost stránky dokumentu.
|
scalePages.pageSize=Velikost stránky dokumentu.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Úroveň přiblížení (oříznutí) stránky.
|
scalePages.scaleFactor=Úroveň přiblížení (oříznutí) stránky.
|
||||||
scalePages.submit=Odeslat
|
scalePages.submit=Odeslat
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Farve
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Indsend
|
|||||||
scalePages.title=Justér sidestørrelse
|
scalePages.title=Justér sidestørrelse
|
||||||
scalePages.header=Justér sidestørrelse
|
scalePages.header=Justér sidestørrelse
|
||||||
scalePages.pageSize=Størrelse på en side i dokumentet.
|
scalePages.pageSize=Størrelse på en side i dokumentet.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Zoom-niveau (beskæring) af en side.
|
scalePages.scaleFactor=Zoom-niveau (beskæring) af en side.
|
||||||
scalePages.submit=Indsend
|
scalePages.submit=Indsend
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Farbe
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Informationen
|
info=Informationen
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Abschicken
|
|||||||
scalePages.title=Seitengröße anpassen
|
scalePages.title=Seitengröße anpassen
|
||||||
scalePages.header=Seitengröße anpassen
|
scalePages.header=Seitengröße anpassen
|
||||||
scalePages.pageSize=Format der Seiten des Dokuments
|
scalePages.pageSize=Format der Seiten des Dokuments
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Zoomstufe (Ausschnitt) einer Seite
|
scalePages.scaleFactor=Zoomstufe (Ausschnitt) einer Seite
|
||||||
scalePages.submit=Abschicken
|
scalePages.submit=Abschicken
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Χρώμα
|
|||||||
sponsor=Yποστηρικτής
|
sponsor=Yποστηρικτής
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Υποβολή
|
|||||||
scalePages.title=Προσαρμογή κλίμακας σελίδας
|
scalePages.title=Προσαρμογή κλίμακας σελίδας
|
||||||
scalePages.header=Προσαρμογή κλίμακας σελίδας
|
scalePages.header=Προσαρμογή κλίμακας σελίδας
|
||||||
scalePages.pageSize=Μέγεθος μιας σελίδας του εγγράφου.
|
scalePages.pageSize=Μέγεθος μιας σελίδας του εγγράφου.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Επίπεδο ζουμ (περικοπή) σελίδας.
|
scalePages.scaleFactor=Επίπεδο ζουμ (περικοπή) σελίδας.
|
||||||
scalePages.submit=Υποβολή
|
scalePages.submit=Υποβολή
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Color
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -115,7 +119,7 @@ navbar.darkmode=Dark Mode
|
|||||||
navbar.language=Languages
|
navbar.language=Languages
|
||||||
navbar.settings=Settings
|
navbar.settings=Settings
|
||||||
navbar.allTools=Tools
|
navbar.allTools=Tools
|
||||||
navbar.multiTool=Multi Tools
|
navbar.multiTool=Multi Tool
|
||||||
navbar.sections.organize=Organize
|
navbar.sections.organize=Organize
|
||||||
navbar.sections.convertTo=Convert to PDF
|
navbar.sections.convertTo=Convert to PDF
|
||||||
navbar.sections.convertFrom=Convert from PDF
|
navbar.sections.convertFrom=Convert from PDF
|
||||||
@@ -231,8 +235,8 @@ home.viewPdf.desc=View, annotate, add text or images
|
|||||||
viewPdf.tags=view,read,annotate,text,image
|
viewPdf.tags=view,read,annotate,text,image
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Tool
|
home.multiTool.title=PDF Multi Tool
|
||||||
home.multiTool.desc=Merge, Rotate, Rearrange, and Remove pages
|
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
||||||
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move
|
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move,delete,migrate,divide
|
||||||
|
|
||||||
home.merge.title=Merge
|
home.merge.title=Merge
|
||||||
home.merge.desc=Easily merge multiple PDFs into one.
|
home.merge.desc=Easily merge multiple PDFs into one.
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Submit
|
|||||||
scalePages.title=Adjust page-scale
|
scalePages.title=Adjust page-scale
|
||||||
scalePages.header=Adjust page-scale
|
scalePages.header=Adjust page-scale
|
||||||
scalePages.pageSize=Size of a page of the document.
|
scalePages.pageSize=Size of a page of the document.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Zoom level (crop) of a page.
|
scalePages.scaleFactor=Zoom level (crop) of a page.
|
||||||
scalePages.submit=Submit
|
scalePages.submit=Submit
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Color
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -115,7 +119,7 @@ navbar.darkmode=Dark Mode
|
|||||||
navbar.language=Languages
|
navbar.language=Languages
|
||||||
navbar.settings=Settings
|
navbar.settings=Settings
|
||||||
navbar.allTools=Tools
|
navbar.allTools=Tools
|
||||||
navbar.multiTool=Multi Tools
|
navbar.multiTool=Multi Tool
|
||||||
navbar.sections.organize=Organize
|
navbar.sections.organize=Organize
|
||||||
navbar.sections.convertTo=Convert to PDF
|
navbar.sections.convertTo=Convert to PDF
|
||||||
navbar.sections.convertFrom=Convert from PDF
|
navbar.sections.convertFrom=Convert from PDF
|
||||||
@@ -231,8 +235,8 @@ home.viewPdf.desc=View, annotate, add text or images
|
|||||||
viewPdf.tags=view,read,annotate,text,image
|
viewPdf.tags=view,read,annotate,text,image
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Tool
|
home.multiTool.title=PDF Multi Tool
|
||||||
home.multiTool.desc=Merge, Rotate, Rearrange, and Remove pages
|
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
||||||
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move
|
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move,delete,migrate,divide
|
||||||
|
|
||||||
home.merge.title=Merge
|
home.merge.title=Merge
|
||||||
home.merge.desc=Easily merge multiple PDFs into one.
|
home.merge.desc=Easily merge multiple PDFs into one.
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Submit
|
|||||||
scalePages.title=Adjust page-scale
|
scalePages.title=Adjust page-scale
|
||||||
scalePages.header=Adjust page-scale
|
scalePages.header=Adjust page-scale
|
||||||
scalePages.pageSize=Size of a page of the document.
|
scalePages.pageSize=Size of a page of the document.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Zoom level (crop) of a page.
|
scalePages.scaleFactor=Zoom level (crop) of a page.
|
||||||
scalePages.submit=Submit
|
scalePages.submit=Submit
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Color
|
|||||||
sponsor=Patrocinador
|
sponsor=Patrocinador
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Entregar
|
|||||||
scalePages.title=Ajustar escala de la página
|
scalePages.title=Ajustar escala de la página
|
||||||
scalePages.header=Adjustar escala de la página
|
scalePages.header=Adjustar escala de la página
|
||||||
scalePages.pageSize=Tamaño de la página del documento
|
scalePages.pageSize=Tamaño de la página del documento
|
||||||
|
scalePages.keepPageSize=Tamaño Original
|
||||||
scalePages.scaleFactor=Nivel de zoom (recorte) de la página
|
scalePages.scaleFactor=Nivel de zoom (recorte) de la página
|
||||||
scalePages.submit=Entregar
|
scalePages.submit=Entregar
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Color
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Entregatu
|
|||||||
scalePages.title=Doitu orrialdearen eskala
|
scalePages.title=Doitu orrialdearen eskala
|
||||||
scalePages.header=Doitu orrialdearen eskala
|
scalePages.header=Doitu orrialdearen eskala
|
||||||
scalePages.pageSize=Dokumentuaren orrialdearen tamaina
|
scalePages.pageSize=Dokumentuaren orrialdearen tamaina
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Orriaren zoom maila (moztea)
|
scalePages.scaleFactor=Orriaren zoom maila (moztea)
|
||||||
scalePages.submit=Entregatu
|
scalePages.submit=Entregatu
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Couleur
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Fusionner
|
|||||||
scalePages.title=Ajuster la taille ou l’échelle
|
scalePages.title=Ajuster la taille ou l’échelle
|
||||||
scalePages.header=Ajuster la taille ou l’échelle
|
scalePages.header=Ajuster la taille ou l’échelle
|
||||||
scalePages.pageSize=Taille d’une page du document
|
scalePages.pageSize=Taille d’une page du document
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Niveau de zoom (recadrage) d’une page
|
scalePages.scaleFactor=Niveau de zoom (recadrage) d’une page
|
||||||
scalePages.submit=Ajuster
|
scalePages.submit=Ajuster
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Dath
|
|||||||
sponsor=Urraitheoir
|
sponsor=Urraitheoir
|
||||||
info=Eolas
|
info=Eolas
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Cuir isteach
|
|||||||
scalePages.title=Coigeartaigh scála an leathanaigh
|
scalePages.title=Coigeartaigh scála an leathanaigh
|
||||||
scalePages.header=Coigeartaigh scála an leathanaigh
|
scalePages.header=Coigeartaigh scála an leathanaigh
|
||||||
scalePages.pageSize=Méid leathanach den doiciméad.
|
scalePages.pageSize=Méid leathanach den doiciméad.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Leibhéal súmáil (barr) de leathanach.
|
scalePages.scaleFactor=Leibhéal súmáil (barr) de leathanach.
|
||||||
scalePages.submit=Cuir isteach
|
scalePages.submit=Cuir isteach
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Color
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=प्रस्तुत क
|
|||||||
scalePages.title=पृष्ठ-स्केल समायोजित करें
|
scalePages.title=पृष्ठ-स्केल समायोजित करें
|
||||||
scalePages.header=पृष्ठ-स्केल समायोजित करें
|
scalePages.header=पृष्ठ-स्केल समायोजित करें
|
||||||
scalePages.pageSize=दस्तावेज़ के पृष्ठ का आकार।
|
scalePages.pageSize=दस्तावेज़ के पृष्ठ का आकार।
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=पृष्ठ का ज़ूम स्तर (क्रॉप)।
|
scalePages.scaleFactor=पृष्ठ का ज़ूम स्तर (क्रॉप)।
|
||||||
scalePages.submit=प्रस्तुत करें
|
scalePages.submit=प्रस्तुत करें
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Boja
|
|||||||
sponsor=Sponzor
|
sponsor=Sponzor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Potvrdi
|
|||||||
scalePages.title=Podesite veličinu stranice
|
scalePages.title=Podesite veličinu stranice
|
||||||
scalePages.header=Podesite veličinu stranice
|
scalePages.header=Podesite veličinu stranice
|
||||||
scalePages.pageSize=Veličina stranice dokumenta.
|
scalePages.pageSize=Veličina stranice dokumenta.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Razina zumiranja (obrezivanje) stranice.
|
scalePages.scaleFactor=Razina zumiranja (obrezivanje) stranice.
|
||||||
scalePages.submit=Potvrdi
|
scalePages.submit=Potvrdi
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Color
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Elküldés
|
|||||||
scalePages.title=Oldalméret beállítása
|
scalePages.title=Oldalméret beállítása
|
||||||
scalePages.header=Oldalméret beállítása
|
scalePages.header=Oldalméret beállítása
|
||||||
scalePages.pageSize=A dokumentum egy oldalának mérete.
|
scalePages.pageSize=A dokumentum egy oldalának mérete.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Az oldal nagyításának szintje (vágás).
|
scalePages.scaleFactor=Az oldal nagyításának szintje (vágás).
|
||||||
scalePages.submit=Küldés
|
scalePages.submit=Küldés
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Color
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Kirim
|
|||||||
scalePages.title=Sesuaikan skala halaman
|
scalePages.title=Sesuaikan skala halaman
|
||||||
scalePages.header=Sesuaikan skala halaman
|
scalePages.header=Sesuaikan skala halaman
|
||||||
scalePages.pageSize=Ukuran halaman dokumen.
|
scalePages.pageSize=Ukuran halaman dokumen.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Tingkat zoom (potong) halaman.
|
scalePages.scaleFactor=Tingkat zoom (potong) halaman.
|
||||||
scalePages.submit=Kirim
|
scalePages.submit=Kirim
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Colore
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Informativa sulla privacy
|
||||||
|
legal.terms=Termini e Condizioni
|
||||||
|
legal.accessibility=Accessibilità
|
||||||
|
legal.cookie=Informativa sui cookie
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Invia
|
|||||||
scalePages.title=Regola la scala della pagina
|
scalePages.title=Regola la scala della pagina
|
||||||
scalePages.header=Regola la scala della pagina
|
scalePages.header=Regola la scala della pagina
|
||||||
scalePages.pageSize=Dimensione di una pagina del documento.
|
scalePages.pageSize=Dimensione di una pagina del documento.
|
||||||
|
scalePages.keepPageSize=Dimensione originale
|
||||||
scalePages.scaleFactor=Livello di zoom (ritaglio) di una pagina.
|
scalePages.scaleFactor=Livello di zoom (ritaglio) di una pagina.
|
||||||
scalePages.submit=Invia
|
scalePages.submit=Invia
|
||||||
|
|
||||||
@@ -965,7 +970,7 @@ watermark.selectText.6=spazio verticale (tra ogni filigrana):
|
|||||||
watermark.selectText.7=Opacità (0% - 100%):
|
watermark.selectText.7=Opacità (0% - 100%):
|
||||||
watermark.selectText.8=Tipo di filigrana:
|
watermark.selectText.8=Tipo di filigrana:
|
||||||
watermark.selectText.9=Immagine filigrana:
|
watermark.selectText.9=Immagine filigrana:
|
||||||
watermark.selectText.10=Convert PDF to PDF-Image
|
watermark.selectText.10=Converti PDF in PDF-Immagine
|
||||||
watermark.submit=Aggiungi Filigrana
|
watermark.submit=Aggiungi Filigrana
|
||||||
watermark.type.1=Testo
|
watermark.type.1=Testo
|
||||||
watermark.type.2=Immagine
|
watermark.type.2=Immagine
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=色
|
|||||||
sponsor=スポンサー
|
sponsor=スポンサー
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=送信
|
|||||||
scalePages.title=ページの縮尺の調整
|
scalePages.title=ページの縮尺の調整
|
||||||
scalePages.header=ページの縮尺の調整
|
scalePages.header=ページの縮尺の調整
|
||||||
scalePages.pageSize=1ページのサイズ
|
scalePages.pageSize=1ページのサイズ
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=1ページの拡大レベル (トリミング)。
|
scalePages.scaleFactor=1ページの拡大レベル (トリミング)。
|
||||||
scalePages.submit=送信
|
scalePages.submit=送信
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=색상
|
|||||||
sponsor=스폰서
|
sponsor=스폰서
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=확인
|
|||||||
scalePages.title=페이지 배율 조절
|
scalePages.title=페이지 배율 조절
|
||||||
scalePages.header=페이지 배율 조절
|
scalePages.header=페이지 배율 조절
|
||||||
scalePages.pageSize=페이지의 크기를 조절합니다.
|
scalePages.pageSize=페이지의 크기를 조절합니다.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=페이지 배율 조절 (잘라내기)
|
scalePages.scaleFactor=페이지 배율 조절 (잘라내기)
|
||||||
scalePages.submit=제출
|
scalePages.submit=제출
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Kleur
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Indienen
|
|||||||
scalePages.title=Pagina-schaal aanpassen
|
scalePages.title=Pagina-schaal aanpassen
|
||||||
scalePages.header=Pagina-schaal aanpassen
|
scalePages.header=Pagina-schaal aanpassen
|
||||||
scalePages.pageSize=Grootte van een pagina van het document.
|
scalePages.pageSize=Grootte van een pagina van het document.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Zoomniveau (uitsnede) van een pagina.
|
scalePages.scaleFactor=Zoomniveau (uitsnede) van een pagina.
|
||||||
scalePages.submit=Indienen
|
scalePages.submit=Indienen
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Farge
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Send inn
|
|||||||
scalePages.title=Juster side-skala
|
scalePages.title=Juster side-skala
|
||||||
scalePages.header=Juster side-skala
|
scalePages.header=Juster side-skala
|
||||||
scalePages.pageSize=Størrelse på et ark i dokumentet.
|
scalePages.pageSize=Størrelse på et ark i dokumentet.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Zoom-nivå (beskjær) for en side.
|
scalePages.scaleFactor=Zoom-nivå (beskjær) for en side.
|
||||||
scalePages.submit=Send inn
|
scalePages.submit=Send inn
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=kolor
|
|||||||
sponsor=sponsor
|
sponsor=sponsor
|
||||||
info=informacje
|
info=informacje
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Wykonaj
|
|||||||
scalePages.title=Dopasuj rozmiar stron
|
scalePages.title=Dopasuj rozmiar stron
|
||||||
scalePages.header=Dopasuj rozmiar stron
|
scalePages.header=Dopasuj rozmiar stron
|
||||||
scalePages.pageSize=Rozmiar stron dokumentu:
|
scalePages.pageSize=Rozmiar stron dokumentu:
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Poziom powiększenia (przycięcia) stron:
|
scalePages.scaleFactor=Poziom powiększenia (przycięcia) stron:
|
||||||
scalePages.submit=Wykonaj
|
scalePages.submit=Wykonaj
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Cor
|
|||||||
sponsor=Patrocine
|
sponsor=Patrocine
|
||||||
info=Informações
|
info=Informações
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Enviar
|
|||||||
scalePages.title=Ajustar Tamanho/Escala da Página
|
scalePages.title=Ajustar Tamanho/Escala da Página
|
||||||
scalePages.header=Ajustar Tamanho/Escala da Página
|
scalePages.header=Ajustar Tamanho/Escala da Página
|
||||||
scalePages.pageSize=Tamanho de uma página do documento.
|
scalePages.pageSize=Tamanho de uma página do documento.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Fator de zoom (corte) de uma página.
|
scalePages.scaleFactor=Fator de zoom (corte) de uma página.
|
||||||
scalePages.submit=Enviar
|
scalePages.submit=Enviar
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Color
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Enviar
|
|||||||
scalePages.title=Ajustar Tamanho/Escala da Página
|
scalePages.title=Ajustar Tamanho/Escala da Página
|
||||||
scalePages.header=Ajustar Tamanho/Escala da Página
|
scalePages.header=Ajustar Tamanho/Escala da Página
|
||||||
scalePages.pageSize=Tamanho de uma página do documento.
|
scalePages.pageSize=Tamanho de uma página do documento.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Fator de zoom (corte) de uma página.
|
scalePages.scaleFactor=Fator de zoom (corte) de uma página.
|
||||||
scalePages.submit=Enviar
|
scalePages.submit=Enviar
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Culoare
|
|||||||
sponsor=Sponsor
|
sponsor=Sponsor
|
||||||
info=Informații
|
info=Informații
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Trimite
|
|||||||
scalePages.title=Ajustează scala paginii
|
scalePages.title=Ajustează scala paginii
|
||||||
scalePages.header=Ajustează scala paginii
|
scalePages.header=Ajustează scala paginii
|
||||||
scalePages.pageSize=Dimensiunea unei pagini a documentului.
|
scalePages.pageSize=Dimensiunea unei pagini a documentului.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Nivel de zoom (decupare) al unei pagini.
|
scalePages.scaleFactor=Nivel de zoom (decupare) al unei pagini.
|
||||||
scalePages.submit=Trimite
|
scalePages.submit=Trimite
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ color=Цвет
|
|||||||
sponsor=Спонсор
|
sponsor=Спонсор
|
||||||
info=Info
|
info=Info
|
||||||
|
|
||||||
|
legal.privacy=Privacy Policy
|
||||||
|
legal.terms=Terms and Conditions
|
||||||
|
legal.accessibility=Accessibility
|
||||||
|
legal.cookie=Cookie Policy
|
||||||
|
legal.impressum=Impressum
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Pipeline #
|
# Pipeline #
|
||||||
@@ -675,6 +679,7 @@ pageLayout.submit=Отправить
|
|||||||
scalePages.title=Отрегулировать масштаб страницы
|
scalePages.title=Отрегулировать масштаб страницы
|
||||||
scalePages.header=Отрегулировать масштаб страницы
|
scalePages.header=Отрегулировать масштаб страницы
|
||||||
scalePages.pageSize=Размер страницы документа.
|
scalePages.pageSize=Размер страницы документа.
|
||||||
|
scalePages.keepPageSize=Original Size
|
||||||
scalePages.scaleFactor=Уровень масштабирования (обрезки) страницы.
|
scalePages.scaleFactor=Уровень масштабирования (обрезки) страницы.
|
||||||
scalePages.submit=Отправить
|
scalePages.submit=Отправить
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user