diff --git a/extensions/ilovepdf/CHANGELOG.md b/extensions/ilovepdf/CHANGELOG.md index c203f56a15fc4..9cfe8ba115645 100644 --- a/extensions/ilovepdf/CHANGELOG.md +++ b/extensions/ilovepdf/CHANGELOG.md @@ -1,3 +1,5 @@ # iLovePDF Changelog +## [Add Compress PDF] - 2024-05-06 + ## [Initial Version] - 2024-04-27 diff --git a/extensions/ilovepdf/package.json b/extensions/ilovepdf/package.json index fb6d5799fbbf9..3ca1626dec2ca 100644 --- a/extensions/ilovepdf/package.json +++ b/extensions/ilovepdf/package.json @@ -1,7 +1,7 @@ { "$schema": "https://www.raycast.com/schemas/extension.json", "name": "ilovepdf", - "title": "iLovePDF", + "title": "ILovePDF", "description": "Set of commands to interact with iLovePDF", "icon": "command-icon.png", "author": "mohamedk1", @@ -16,6 +16,13 @@ "subtitle": "iLovePDF", "description": "Converts an image to pdf using iLovePDF API.", "mode": "view" + }, + { + "name": "compress-pdf", + "title": "Compress PDF", + "subtitle": "iLovePDF", + "description": "Compresses pdf using iLovePDF API.", + "mode": "view" } ], "preferences": [ diff --git a/extensions/ilovepdf/src/compress-pdf.tsx b/extensions/ilovepdf/src/compress-pdf.tsx new file mode 100644 index 0000000000000..1a0bd6d1c8251 --- /dev/null +++ b/extensions/ilovepdf/src/compress-pdf.tsx @@ -0,0 +1,156 @@ +import { + Form, + ActionPanel, + Action, + showToast, + getPreferenceValues, + Toast, + closeMainWindow, + open, + openExtensionPreferences, +} from "@raycast/api"; +import ILovePDFApi from "@ilovepdf/ilovepdf-nodejs"; +import CompressTask from "@ilovepdf/ilovepdf-js-core/tasks/CompressTask"; +import ILovePDFFile from "@ilovepdf/ilovepdf-nodejs/ILovePDFFile"; +import { useState } from "react"; +import fs from "fs"; +import path from "path"; + +type Values = { + files: string[]; + compression_level: "low" | "recommended" | "extreme"; +}; + +type Status = "init" | "success" | "failure"; + +const { APIPublicKey: publicKey, APISecretKey: secretKey, OpenNow: openNow } = getPreferenceValues(); + +function getDestinationFile(files: string[]): string { + if (!files.length) { + return ""; + } + const file = files[0]; + const fileExtension = path.extname(file); + const fileName = path.basename(file, fileExtension); + const directory = path.dirname(file); + if (files.length == 1) { + return path.join(directory, `${fileName}_compressed.pdf`); + } + return path.join(directory, `compressed_pdfs.zip`); +} + +function getSavedPercentage(originalFile: string, compressedFile: string) { + const originalSize = fs.statSync(originalFile).size; + const compressedSize = fs.statSync(compressedFile).size; + return 100 - Math.floor((compressedSize / originalSize) * 100); +} + +export default function Command() { + const [isLoading, setIsLoading] = useState(false); + const [status, setStatus] = useState("init"); + const [destinationFilePath, setDestinationFilePath] = useState(""); + + async function handleSubmit(values: Values) { + setIsLoading(true); + if (!values.files.length) { + await showToast(Toast.Style.Failure, "You must select at least a single pdf file", "Please select a file"); + setStatus("failure"); + setIsLoading(false); + return; + } + + const toast = await showToast(Toast.Style.Animated, "Processing", "Compressing PDF..."); + + let destinationFile = ""; + const instance = new ILovePDFApi(publicKey, secretKey); + const task = instance.newTask("compress") as CompressTask; + const addedFilesPromises = []; + try { + await task.start(); + for (const file of values.files) { + const fileExtension = path.extname(file); + if (fileExtension != ".pdf") { + toast.style = Toast.Style.Failure; + toast.title = "failure"; + toast.message = "You must select a PDF file."; + setStatus("failure"); + setIsLoading(false); + console.log(`file is not a PDF received extension is ${fileExtension}`); + return; + } + const iLovePdfFile = new ILovePDFFile(file); + addedFilesPromises.push(task.addFile(iLovePdfFile)); + } + await Promise.all(addedFilesPromises); + destinationFile = getDestinationFile(values.files); + setDestinationFilePath(destinationFile); + await task.process({ compression_level: values.compression_level }); + const data = await task.download(); + fs.writeFileSync(destinationFile, data); + + toast.style = Toast.Style.Success; + toast.title = "success"; + toast.message = + "Compressed successfully." + + (values.files.length == 1 + ? ` Your PDF is ${getSavedPercentage(values.files[0], destinationFile)}% smaller` + : ""); + setStatus("success"); + setIsLoading(false); + } catch (error) { + toast.style = Toast.Style.Failure; + toast.title = "failure"; + toast.message = "Error happened during compressing the file."; + setStatus("failure"); + setIsLoading(false); + console.log(error); + return; + } + + if (openNow) { + await closeMainWindow(); + open(destinationFile); + } else { + toast.primaryAction = { + title: "Open File", + onAction: () => { + open(destinationFile); + }, + }; + } + } + + return ( +
+ + {status == "success" ? : null} + {status == "success" ? ( + + ) : null} + {status == "success" ? ( + { + open(destinationFilePath); + }} + /> + ) : null} + {status == "failure" ? ( + + ) : null} + + } + isLoading={isLoading} + > + + + + + + + + ); +}