From 929f0bbbe5aa431b0268795c48f471ecedfe36d3 Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Sat, 20 Jul 2024 09:53:58 +0100 Subject: [PATCH] version bump, multi file fix and disable survey (#1550) * version bump, multi file fix and disable survey * example test stuff * logs * Update docker-compose-latest.yml --------- Co-authored-by: a --- build.gradle | 2 +- chart/stirling-pdf/Chart.yaml | 2 +- cucumber/exampleFiles/ghost1.pdf | Bin 0 -> 2594 bytes cucumber/exampleFiles/ghost2.pdf | Bin 0 -> 2589 bytes cucumber/exampleFiles/ghost3.pdf | Bin 0 -> 2593 bytes cucumber/exampleFiles/images.pdf | Bin 0 -> 20615 bytes cucumber/exampleFiles/pdfa1.pdf | Bin 0 -> 2591 bytes cucumber/exampleFiles/pdfa2.pdf | Bin 0 -> 2594 bytes cucumber/features/environment.py | 5 + cucumber/features/examples.feature | 2 +- cucumber/features/external.feature | 17 +-- cucumber/features/general.feature | 20 ++++ cucumber/features/steps/step_definitions.py | 112 +++++++++++++++--- exampleYmlFiles/docker-compose-latest.yml | 1 - .../api/misc/CompressController.java | 2 +- .../convert/pdf-to-presentation.html | 2 +- .../templates/convert/pdf-to-word.html | 2 +- src/main/resources/templates/home.html | 3 +- .../resources/templates/remove-pages.html | 2 +- .../templates/security/add-watermark.html | 4 +- test.sh | 3 + 21 files changed, 137 insertions(+), 42 deletions(-) create mode 100644 cucumber/exampleFiles/ghost1.pdf create mode 100644 cucumber/exampleFiles/ghost2.pdf create mode 100644 cucumber/exampleFiles/ghost3.pdf create mode 100644 cucumber/exampleFiles/images.pdf create mode 100644 cucumber/exampleFiles/pdfa1.pdf create mode 100644 cucumber/exampleFiles/pdfa2.pdf diff --git a/build.gradle b/build.gradle index 90e130f6c4a..e5460c19bf7 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ ext { } group = "stirling.software" -version = "0.26.1" +version = "0.26.2" // 17 is lowest but we support and recommend 21 sourceCompatibility = "17" diff --git a/chart/stirling-pdf/Chart.yaml b/chart/stirling-pdf/Chart.yaml index ebe8dd48baf..9b633ddb5bc 100644 --- a/chart/stirling-pdf/Chart.yaml +++ b/chart/stirling-pdf/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -appVersion: 0.26.1 +appVersion: 0.26.2 description: locally hosted web application that allows you to perform various operations on PDF files home: https://github.com/Stirling-Tools/Stirling-PDF diff --git a/cucumber/exampleFiles/ghost1.pdf b/cucumber/exampleFiles/ghost1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4e497da02abb98ee21a8ccfac3c336eca1614c8d GIT binary patch literal 2594 zcmdT`Sy$pn6n@XIC~N}AmIcBlqCf~nkS&NJpk%2)?2v>?GU`0cADDTY_xY_;MXOCa z^y$;{);Szf_2t&Bd%wF>(F0M+aM>J1|NYmW|9}znToiOw4YZ*Hks3e)U!=_!kLvbL&ab$3H?fCaAhNL8y8BXNMo(-BpxQP436Oy+N&8>$Z_7b{~f zp#2*REL{am%h6rKa#n!3v7EZ&TVH{mx`BWwWt310UOYS*<9|FSFZ>1T+S@9(w^b8= z!e;xROzZ*76*Mfh;XZ>Ip0l99@t|1d!2&P?6%qeRU*ty6cSEE@AME@g#u5jyh5>SQ z1qN6FLx^F<@EJQIZ`2iRyuO>SZy7AGS%4Y20VWbJXU0f%b}9)@fj0*Rc=4VCc`W+I z)w=^6vG-T;Kse~ZD}%p83<`T5knmi&2F|o=ANE`a4+!MHCCisAY^s53yQ{r87WZ`2 z!(i$gSur}(7;=c zt-!`!g-$>QI|Qkohx-X5skXnL@1*9w<~v>ia@c+g+dji1lJ%q_Mu241h}7yA!gn#) zqnniYn;OZo1MCYf(z?==<&q#m++Ikpurb-M6RfEVomH>~JjW76et;vgq1vi<-qwoc z)NNck5@ySmdD$29m5o@Xlc$?hujY#FbgkD}RqS4S{@aUpH>Q9oXWBXz{a z#i^B?W-CtXN~*i#s}nTn(k*GRY?^MXJFy>z>7%Yvp)L8Or_W+qJDV&B{RPy`4i`^W zYr^2cpM}26c}?Z?F6o)NCkVN=>V`AXHkUfRp-#qGA8 ziKo|>7gFX^4a4GWUN##hZ0#gIW*@hrKcsdATPuVKcZ_3kjeo#+4m1A&%O8*v z%D97kkRzx1N32x9XXv+b94FvT{{iE9+_^ts!U3$bj|E7zY>0OEA6W#{tjZdKZnF6z zEDCwZ3TDX=ig}YQ6pJOHR21~uk0llqy>}&B9lnxfGQhC#afDm&_iks$6vfDn=>l>j kjVOF0aRWe(I6PLY-ysRuuK%eh*oBbi_##Eqt-eJ43z@~;&;S4c literal 0 HcmV?d00001 diff --git a/cucumber/exampleFiles/ghost2.pdf b/cucumber/exampleFiles/ghost2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6b2f529b8adceae20befc0acc154441dcb9c891a GIT binary patch literal 2589 zcmdT`Nps>j6u$dcC=j#60WV+-ga#A#o!CH{umoevV8BbfOp-awADFq#eSYgmbdsji znd<7QxwMNydQVSJZ~Y{4Sgj}6WQrjF{_D?wfCL@e^}EU%G@u1t#fKU|5Jq>OID z!*9?xR0YsAOSLt_+5r02u*#Nad}Z_%69TN1mV>qb>>y%<{t=A_w1RY<9F;mbs)Ck~ z*&fJYdjQ>onxS0VPhf^<24q+c2ssWc06kP(>|geaoCG~Pa8>Amqd(YK>>$!GbZu3J zK2kvAz|bT3gdAy^$_8G)jFp$M1s2FGKufld0*SWMBUiDGDlwk`uMP~+<`W0fNc1&U zZw|27-e1K7{zDI5BKS+>AamjYPEXI)P^FDM*tab-!7T5!SiV$YMe&t`y*bIFaH69e z_*>frF~zd2XVVV6IG`&oRD8p>s<=90)jY>=X+~hPTq?z+(iFo)(eG6bZ~oeyxb(Wl z+Ev_VkO1FxBiht~&yTjNc_4-eWc`m0L3OPKD*U-qa0#QH+(Fd`vB2^is2aKfHFV_2 z@DIqV!1D3r$Z-|NL3l#fm4kO$@3`l_);rn(QpkP-**-%vT=lpkB!H_*!oB(>;Kv-C zgd4Z`tD3rT@R2X5Ny~Dj)ync!h~Ncd#Q_ETg+Q9R(AxN0z%c?=9&h#z^+mq&Gq3?Fh)^$Epb#Ezd?ywp0V&yI?&duFjGs+Ej z4_YA^+4i{cfIPo7&V5LxZ%p~BPz&A2^D_;;RDQ1bspYN6=2?P%A$`ef*ZE3Y`Y5Uxk5vr-XX53Z z-ZHmw@|^J}mAul}hb})U?RGOvrx!-@w(aKBkZP=_X1xu zQtKqfW4LdRv|0JQzl_B?%P><7R)%;YdGCx_G=hxrL9Cu!s1poeIf8lnK!)d2JkY@#Pe2WgKVZG_SO&HCJ08cP$iL&I zKak^d2t3}&;S2peFPlNv=eKe!%Oj9~$KyBz+V6Ng_nmzRqfgH8UBx&+_xSW_RRJ+8 zAQ;zGo=1k9`YGh$RK=I6fMQ5x#Eu{76f_n8ryvQ8cQUAW}ur0q3?e^%;E$= qw=CTT_%@OV^cb;yfNwW6myO>cPS_Fp6xTndkYhQHAj#UGPW%gj8QM_* literal 0 HcmV?d00001 diff --git a/cucumber/exampleFiles/ghost3.pdf b/cucumber/exampleFiles/ghost3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ea0516614c75d264feb0491dfa0bdc96cb4061c7 GIT binary patch literal 2593 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 literal 0 HcmV?d00001 diff --git a/cucumber/exampleFiles/pdfa1.pdf b/cucumber/exampleFiles/pdfa1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2873c0d464bd633401ed9511e23d214ef8999978 GIT binary patch literal 2591 zcmdT`Sy$pn6n@XIC{Y$=$xZ?)5#L$0V?ubKWsuBTp|bgFhnN662NqgXoH*( zEW*$$()8owW6s~ouA!bY+zrJ72Dti?Iys@}8Vfi~s#K{&A;%tcNO=cBHX^b9DYPR$j&im|(L2t-2uw5^tw(eCTXd5y5b`k+OAV2*^#OiIffG$iIq8?XLupaFiHG-l_Q(qtCOT&)7E|H zKZ7jzt{U;CYxMl+`ep!9n84Qm=n$OOW@MnBJB6e$uE`}bLXe7_z(a;@*~r94-q_(9 zdlfk$nQS>e^gP^8=o(xHyZKIP?mge}4!~pkZEX7p&q&sjickT`DwWjgSHQP1*nyjr z_^Xl%GQ51wYA{*)wdgaS;qr+PX zq3Msxnvl5Rpo;E>d^=f)W!i=hOQI58Pp?vL**`nI=$7=!V$>`ThVp~7KQfB@b*?z2 zPxXw)PcsQC+sh^E@xA_8ygjyWA?r0;>jf>aV?{2THL=XVbur7HHIJ+Drq|@>YXC?DKet%4N`a_!A+)C%1_Ps*kM3HZGx5Ky!qQ2$dbL?5W2#+p z_JrAVBQS-*V1^DAHF@M;22Oq>6>_Ycp6c-QL5+eSmR0ywy6_oR-&|`ynN%$E5vxg> zxu~ZQeP6bR^+_?uTIcoa*5=BQvwHG;O5`O0g%j*PWW>HzlNG z0zr(Sz6MvV;{qosN`{SPo5RC|Go<0-RK6cb#j{~+S-vVC`;s{eCqrgz@`YBsc(9U3 znpll-t_D3JkeT(_CtyAK$f6j)auoCSfxIa4BCx<4Pr@ZlKH$9ZSOypP2Oh^_=s)m; zPvpb`ZXX}y$d&$)C+G16`mG$xinz^x;Bg#o+aGu$_npn8OTWv7KD5`!-#&gCRX~kS zWEq(VaRNelNjD`kuS$t-|$?se@7%>+vW%Ta2rC7tG#T)xh0D}`?hz*1#1dJ`fES9lNGwDPBK>ODB{?*#!VmiiGMn~O4K$J4dapAsLnCRhuOp^hxU|nZN31>%D@e(%M z0U2TsVA@bO)Eo2}Ofb!YB*%kPh6hu?bXA++OMj7*p@WXL1|4w1LyRQ=v4*aVGzGd? z0Yec=I||Uq=Z{u~~qTk&7LPw=+FkHBTxDp8{_Hx_I*$fH)R?^VK^5 zj@bLNAV_?O;MIdaMGTT>2uOI^NXMDhcVGvZctTjtTe5t~!m8@3JG45BW9m#t<>;=F z4QSOw=F1)(oe*HEHdI{$nKhCfbS=xXe4I^jXS(%Ta^l#kW#N9pi0aNc&v#ODU-KRB00Oq(z_w5DjAT8j2pN#9l1Z(8arh|)XYM8? z{-#DWb}q((i?pItB`KY#LEK(Quh?N{zY zZGPY>8Y3gWnw!J5=dNUyuiPhl#9f7-*kG}6lWrzqPUIf;4PS(Y3d_>>FcZjrDw|R| zm8tcdUc}rCD>tQiI$Ml1P2pM|cn<4$E>KSTr}@n2x_CdH#>NShlPlxlDy2_+;f1ws zIGIsNtG-S+Q}-cXG~c-P_^cF6ZlatsKFZ_$5r>ae~oIC8$<^XmJ#J*?$C%6zs_GOd1?mi;g|@INT+WwRTzhU5DE zp?7~M1Zop$(pBg}sTqgRS*KoY(JfuFQi`NGtiAuerDr0?VRpB3I~J{V<#Wgy|lI2HT}`XyjNB>fiAsC z#>&3o`f*?llTt(R*vHmxYJ+ocpi7|3toc%UM_tu=h~{VgZAnDBh>&k z$;X$PmgZG9omj#Y2ZgvQ@H)5P1uebE2$^N^#}ZS@fA%C>ef%VgMuBeN>j<~te|nvT sD2kEHB?9D1k}3QmK`tOy9G)x2uaE@n)c;i5J%y0x_!Q;$*FTBW-vnRaTmS$7 literal 0 HcmV?d00001 diff --git a/cucumber/features/environment.py b/cucumber/features/environment.py index ec7f2c9ff3f..ca56b21f196 100644 --- a/cucumber/features/environment.py +++ b/cucumber/features/environment.py @@ -14,3 +14,8 @@ def after_scenario(context, scenario): os.remove('response_file') if hasattr(context, 'file_name') and os.path.exists(context.file_name): os.remove(context.file_name) + + # Remove any temporary files + for temp_file in os.listdir('.'): + if temp_file.startswith('genericNonCustomisableName') or temp_file.startswith('temp_image_'): + os.remove(temp_file) \ No newline at end of file diff --git a/cucumber/features/examples.feature b/cucumber/features/examples.feature index 04e4081fa65..c6477466fd7 100644 --- a/cucumber/features/examples.feature +++ b/cucumber/features/examples.feature @@ -1,4 +1,4 @@ -@example +@example @general Feature: API Validation @positive @password diff --git a/cucumber/features/external.feature b/cucumber/features/external.feature index 1d503135de5..c1330f523c3 100644 --- a/cucumber/features/external.feature +++ b/cucumber/features/external.feature @@ -32,7 +32,7 @@ Feature: API Validation @ocr @positive Scenario: Extract Image Scans Given I generate a PDF file as "fileInput" - And the pdf contains 3 images on 2 pages + And the pdf contains 3 images of size 300x300 on 2 pages And the request data includes | parameter | value | | angleThreshold | 5 | @@ -125,8 +125,7 @@ Feature: API Validation @ocr Scenario: PDFA - Given I generate a PDF file as "fileInput" - And the pdf contains 3 pages with random text + Given I use an example file at "exampleFiles/pdfa2.pdf" as parameter "fileInput" And the request data includes | parameter | value | | outputFormat | pdfa | @@ -137,8 +136,7 @@ Feature: API Validation @ocr Scenario: PDFA1 - Given I generate a PDF file as "fileInput" - And the pdf contains 3 pages with random text + Given I use an example file at "exampleFiles/pdfa1.pdf" as parameter "fileInput" And the request data includes | parameter | value | | outputFormat | pdfa-1 | @@ -149,8 +147,7 @@ Feature: API Validation @compress @ghostscript @positive Scenario: Compress - Given I generate a PDF file as "fileInput" - And the pdf contains 3 pages with random text + Given I use an example file at "exampleFiles/ghost3.pdf" as parameter "fileInput" And the request data includes | parameter | value | | optimizeLevel | 4 | @@ -161,8 +158,7 @@ Feature: API Validation @compress @ghostscript @positive Scenario: Compress - Given I generate a PDF file as "fileInput" - And the pdf contains 3 pages with random text + Given I use an example file at "exampleFiles/ghost2.pdf" as parameter "fileInput" And the request data includes | parameter | value | | optimizeLevel | 1 | @@ -175,8 +171,7 @@ Feature: API Validation @compress @ghostscript @positive Scenario: Compress - Given I generate a PDF file as "fileInput" - And the pdf contains 3 pages with random text + Given I use an example file at "exampleFiles/ghost1.pdf" as parameter "fileInput" And the request data includes | parameter | value | | optimizeLevel | 1 | diff --git a/cucumber/features/general.feature b/cucumber/features/general.feature index 229d37b50c6..345f59cbc8d 100644 --- a/cucumber/features/general.feature +++ b/cucumber/features/general.feature @@ -94,3 +94,23 @@ Feature: API Validation | 1 | 10 | 2 | 10 | + @extract-images + Scenario Outline: Extract Image Scans + Given I use an example file at "exampleFiles/images.pdf" as parameter "fileInput" + And the request data includes + | parameter | value | + | format | | + When I send the API request to the endpoint "/api/v1/misc/extract-images" + Then the response content type should be "application/octet-stream" + And the response file should have extension ".zip" + And the response ZIP should contain 20 files + And the response file should have size greater than 0 + And the response status code should be 200 + + Examples: + | format | + | png | + | gif | + | jpeg | + + diff --git a/cucumber/features/steps/step_definitions.py b/cucumber/features/steps/step_definitions.py index 60479b6eac3..65a49fda0ad 100644 --- a/cucumber/features/steps/step_definitions.py +++ b/cucumber/features/steps/step_definitions.py @@ -6,11 +6,14 @@ import random import string from reportlab.lib.pagesizes import letter +from reportlab.lib.utils import ImageReader from reportlab.pdfgen import canvas import mimetypes import requests import zipfile import shutil +import re +from PIL import Image, ImageDraw ######### # GIVEN # @@ -43,8 +46,6 @@ def step_use_example_file(context, filePath, fileInput): except FileNotFoundError: raise FileNotFoundError(f"The example file '{filePath}' does not exist.") - - @given('the pdf contains {page_count:d} pages') def step_pdf_contains_pages(context, page_count): writer = PdfWriter() @@ -66,8 +67,6 @@ def step_pdf_contains_blank_pages(context, page_count): context.files[context.param_name].close() context.files[context.param_name] = open(context.file_name, 'rb') - - def create_black_box_image(file_name, size): can = canvas.Canvas(file_name, pagesize=size) width, height = size @@ -76,36 +75,75 @@ def create_black_box_image(file_name, size): can.showPage() can.save() -def create_pdf_with_black_boxes(file_name, image_count, page_count): - page_width, page_height = letter - box_size = 72 # 1 inch by 1 inch black box +@given(u'the pdf contains {image_count:d} images of size {width:d}x{height:d} on {page_count:d} pages') +def step_impl(context, image_count, width, height, page_count): + context.param_name = "fileInput" + context.file_name = "genericNonCustomisableName.pdf" + create_pdf_with_images_and_boxes(context.file_name, image_count, page_count, width, height) + if not hasattr(context, 'files'): + context.files = {} + context.files[context.param_name] = open(context.file_name, 'rb') + +def add_black_boxes_to_image(image): + if isinstance(image, str): + image = Image.open(image) + + draw = ImageDraw.Draw(image) + draw.rectangle([(0, 0), image.size], fill=(0, 0, 0)) # Fill image with black + return image + +def create_pdf_with_images_and_boxes(file_name, image_count, page_count, image_width, image_height): + page_width, page_height = max(letter[0], image_width), max(letter[1], image_height) boxes_per_page = image_count // page_count + (1 if image_count % page_count != 0 else 0) - + writer = PdfWriter() box_counter = 0 - + for page in range(page_count): packet = io.BytesIO() - can = canvas.Canvas(packet, pagesize=letter) - + can = canvas.Canvas(packet, pagesize=(page_width, page_height)) + for i in range(boxes_per_page): if box_counter >= image_count: break - x = (i % (page_width // box_size)) * box_size - y = page_height - ((i // (page_width // box_size) + 1) * box_size) - can.setFillColorRGB(0, 0, 0) - can.rect(x, y, box_size, box_size, fill=1) + + # Simulating a dynamic image creation (replace this with your actual image creation logic) + # For demonstration, we'll create a simple black image + dummy_image = Image.new('RGB', (image_width, image_height), color='white') # Create a white image + dummy_image = add_black_boxes_to_image(dummy_image) # Add black boxes + + # Convert the PIL Image to bytes to pass to drawImage + image_bytes = io.BytesIO() + dummy_image.save(image_bytes, format='PNG') + image_bytes.seek(0) + + # Check if the image fits in the current page dimensions + x = (i % (page_width // image_width)) * image_width + y = page_height - (((i % (page_height // image_height)) + 1) * image_height) + + if x + image_width > page_width or y < 0: + break + + # Add the image to the PDF + can.drawImage(ImageReader(image_bytes), x, y, width=image_width, height=image_height) box_counter += 1 - + can.showPage() can.save() packet.seek(0) new_pdf = PdfReader(packet) writer.add_page(new_pdf.pages[0]) - + + # Write the PDF to file with open(file_name, 'wb') as f: writer.write(f) + # Clean up temporary image files + for i in range(image_count): + temp_image_path = f"temp_image_{i}.png" + if os.path.exists(temp_image_path): + os.remove(temp_image_path) + @given('the pdf contains {image_count:d} images on {page_count:d} pages') def step_pdf_contains_images(context, image_count, page_count): if not hasattr(context, 'param_name'): @@ -118,7 +156,6 @@ def step_pdf_contains_images(context, image_count, page_count): context.files[context.param_name].close() context.files[context.param_name] = open(context.file_name, 'rb') - @given('the pdf contains {page_count:d} pages with random text') def step_pdf_contains_pages_with_random_text(context, page_count): buffer = io.BytesIO() @@ -186,6 +223,21 @@ def save_generated_pdf(context, filename): # WHEN # ######## +@when('I send a GET request to "{endpoint}"') +def step_send_get_request(context, endpoint): + base_url = "http://localhost:8080" + full_url = f"{base_url}{endpoint}" + response = requests.get(full_url) + context.response = response + +@when('I send a GET request to "{endpoint}" with parameters') +def step_send_get_request_with_params(context, endpoint): + base_url = "http://localhost:8080" + params = {row['parameter']: row['value'] for row in context.table} + full_url = f"{base_url}{endpoint}" + response = requests.get(full_url, params=params) + context.response = response + @when('I send the API request to the endpoint "{endpoint}"') def step_send_api_request(context, endpoint): url = f"http://localhost:8080{endpoint}" @@ -278,7 +330,6 @@ def step_save_response_file(context, filename): f.write(context.response.content) print(f"Saved response content to {filename}") - @then('the response PDF should contain {page_count:d} pages') def step_check_response_pdf_page_count(context, page_count): response_file = io.BytesIO(context.response.content) @@ -305,3 +356,26 @@ def step_check_response_zip_doc_page_count(context, doc_count, pages_per_doc): reader = PdfReader(pdf_file) actual_pages_per_doc = len(reader.pages) assert actual_pages_per_doc == pages_per_doc, f"Expected {pages_per_doc} pages per document but got {actual_pages_per_doc} pages in document {file_name}" + +@then('the JSON value of "{key}" should be "{expected_value}"') +def step_check_json_value(context, key, expected_value): + actual_value = context.response.json().get(key) + assert actual_value == expected_value, \ + f"Expected JSON value for '{key}' to be '{expected_value}' but got '{actual_value}'" + +@then('JSON list entry containing "{identifier_key}" as "{identifier_value}" should have "{target_key}" as "{target_value}"') +def step_check_json_list_entry(context, identifier_key, identifier_self, target_key, target_value): + json_response = context.response.json() + for entry in json_response: + if entry.get(identifier_key) == identifier_value: + assert entry.get(target_key) == target_value, \ + f"Expected {target_key} to be {target_value} in entry where {identifier_key} is {identifier_value}, but found {entry.get(target_key)}" + break + else: + raise AssertionError(f"No entry with {identifier_key} as {identifier_value} found") + +@then('the response should match the regex "{pattern}"') +def step_response_matches_regex(context, pattern): + response_text = context.response.text + assert re.match(pattern, response_text), \ + f"Response '{response_text}' does not match the expected pattern '{pattern}'" diff --git a/exampleYmlFiles/docker-compose-latest.yml b/exampleYmlFiles/docker-compose-latest.yml index 794eb1be4fe..6090e291e3d 100644 --- a/exampleYmlFiles/docker-compose-latest.yml +++ b/exampleYmlFiles/docker-compose-latest.yml @@ -22,7 +22,6 @@ services: DOCKER_ENABLE_SECURITY: "false" SECURITY_ENABLELOGIN: "false" LANGS: "en_GB,en_US,ar_AR,de_DE,fr_FR,es_ES,zh_CN,zh_TW,ca_CA,it_IT,sv_SE,pl_PL,ro_RO,ko_KR,pt_BR,ru_RU,el_GR,hi_IN,hu_HU,tr_TR,id_ID" - INSTALL_BOOK_AND_ADVANCED_HTML_OPS: "true" SYSTEM_DEFAULTLOCALE: en-US UI_APPNAME: Stirling-PDF UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest diff --git a/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java b/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java index 12dd625c428..2240dbed229 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/misc/CompressController.java @@ -99,7 +99,7 @@ public ResponseEntity optimizePdf(@ModelAttribute OptimizePdfRequest req List command = new ArrayList<>(); command.add("gs"); command.add("-sDEVICE=pdfwrite"); - command.add("-dCompatibilityLevel=1.4"); + command.add("-dCompatibilityLevel=1.5"); switch (optimizeLevel) { case 1: diff --git a/src/main/resources/templates/convert/pdf-to-presentation.html b/src/main/resources/templates/convert/pdf-to-presentation.html index 794317609c2..ce1f455dd5d 100644 --- a/src/main/resources/templates/convert/pdf-to-presentation.html +++ b/src/main/resources/templates/convert/pdf-to-presentation.html @@ -22,8 +22,8 @@
diff --git a/src/main/resources/templates/convert/pdf-to-word.html b/src/main/resources/templates/convert/pdf-to-word.html index 7e5f96c03a9..0fd004f2e5f 100644 --- a/src/main/resources/templates/convert/pdf-to-word.html +++ b/src/main/resources/templates/convert/pdf-to-word.html @@ -22,8 +22,8 @@
diff --git a/src/main/resources/templates/home.html b/src/main/resources/templates/home.html index ffb25a3705a..d2846a2418e 100644 --- a/src/main/resources/templates/home.html +++ b/src/main/resources/templates/home.html @@ -264,6 +264,7 @@