|
| 1 | +import os |
| 2 | +import shutil |
| 3 | +import json |
| 4 | +import logging |
| 5 | +from pathlib import Path |
| 6 | +from asposepdfcloud import ApiClient, PdfApi |
| 7 | +from asposepdfcloud import AsposeResponse, DocumentPageResponse, Page, Rectangle, DocumentConfig, DocumentProperties, DocumentProperty, DisplayProperties, DefaultPageConfig |
| 8 | +from asposepdfcloud import ImageStamp, HorizontalAlignment, VerticalAlignment, Rotation |
| 9 | + |
| 10 | +# Configure logging |
| 11 | +logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") |
| 12 | + |
| 13 | +class Config: |
| 14 | + """Configuration parameters.""" |
| 15 | + CREDENTIALS_FILE = Path(r"credentials.json") |
| 16 | + LOCAL_FOLDER = Path(r"C:\Samples") |
| 17 | + REMOTE_FOLDER = "Your_Temp_Pdf_Cloud" |
| 18 | + PDF_DOCUMENT = "sample.pdf" |
| 19 | + PDF_OUTPUT = "output_sample.pdf" |
| 20 | + |
| 21 | + ROTATE_PAGES_ANGLE = Rotation.ON90 |
| 22 | + ROTATE_PAGES = "1-3" |
| 23 | + |
| 24 | + CROP_PAGE_TEMP_FILE = "sammple_temp_file.png" |
| 25 | + CROP_LOCAL_RESULT_DOCUMENT_NAME = "output_sample.pdf" |
| 26 | + CROP_PAGE_NUMBER = 3 |
| 27 | + CROP_HEIGHT = 400 |
| 28 | + CROP_WIDTH = 300 |
| 29 | + CROP_LLX = 100 |
| 30 | + CROP_LLY = 200 |
| 31 | + |
| 32 | + RESIZE_PDF_HTML_FILE = "sammple_temp_file.html" |
| 33 | + RESIZE_RESULT_DOCUMENT_NAME = "output_sample.pdf" |
| 34 | + RESIZE_PAGE_NUMBER = 2 |
| 35 | + RESIZE_NEW_PAGE_WIDTH = 1000 |
| 36 | + RESIZE_NEW_PAGE_HEIGHT = 500 |
| 37 | + |
| 38 | + CROP_PAGE_WIDTH = 0 |
| 39 | + CROP_PAGE_HEIGHT = 0 |
| 40 | + |
| 41 | + |
| 42 | +class PdfChangeLayoutHelper: |
| 43 | + def __init__(self, credentials_file: Path): |
| 44 | + self.pdf_api = None |
| 45 | + self._init_api(credentials_file) |
| 46 | + |
| 47 | + def _init_api(self, credentials_file: Path): |
| 48 | + """Initialize the API client.""" |
| 49 | + try: |
| 50 | + with credentials_file.open("r", encoding="utf-8") as file: |
| 51 | + credentials = json.load(file) |
| 52 | + api_key, app_id = credentials.get("key"), credentials.get("id") |
| 53 | + if not api_key or not app_id: |
| 54 | + raise ValueError("Error: Missing API keys in the credentials file.") |
| 55 | + self.pdf_api = PdfApi(ApiClient(api_key, app_id)) |
| 56 | + except (FileNotFoundError, json.JSONDecodeError, ValueError) as e: |
| 57 | + logging.error(f"Failed to load credentials: {e}") |
| 58 | + |
| 59 | + def uploadFile(self, fileName: str, localFolder: Path, remoteFolder: str): |
| 60 | + """ Upload a local fileName to the Aspose Cloud server. """ |
| 61 | + if self.pdf_api: |
| 62 | + file_path = localFolder / fileName |
| 63 | + try: |
| 64 | + self.pdf_api.upload_file(os.path.join(remoteFolder, fileName), file_path) |
| 65 | + logging.info(f"upload_file(): File '{fileName}' uploaded successfully.") |
| 66 | + except Exception as e: |
| 67 | + logging.error(f"upload_document(): Failed to upload file: {e}") |
| 68 | + |
| 69 | + |
| 70 | + def downloadFile(self, document: str, outputDocument: str, localFolder: Path, remoteFolder: Path, output_prefix: str): |
| 71 | + """Download the processed PDF document from the Aspose Cloud server.""" |
| 72 | + if self.pdf_api: |
| 73 | + try: |
| 74 | + temp_file = self.pdf_api.download_file(str(remoteFolder) + '/' + document) |
| 75 | + local_path = localFolder / ( output_prefix + outputDocument ) |
| 76 | + shutil.move(temp_file, str(local_path)) |
| 77 | + logging.info(f"download_result(): File successfully downloaded: {local_path}") |
| 78 | + except Exception as e: |
| 79 | + logging.error(f"download_result(): Failed to download file: {e}") |
| 80 | + |
| 81 | + def getPageInfo(self, document: str, pageNumber: int, tempFolder: str): |
| 82 | + if self.pdf_api: |
| 83 | + args = { |
| 84 | + "folder": tempFolder, |
| 85 | + } |
| 86 | + response: DocumentPageResponse = self.pdf_api.get_page(document, pageNumber, **args) |
| 87 | + |
| 88 | + if response.code == 200: |
| 89 | + logging.info(f"page {pageNumber} => id: '{response.page.id}', lLx: '{response.page.rectangle.llx}', lLY: '{response.page.rectangle.lly}', uRX: '{response.page.rectangle.urx}', uRY: '{response.page.rectangle.ury}'") |
| 90 | + Config.CROP_PAGE_HEIGHT = response.page.rectangle.ury - response.page.rectangle.lly |
| 91 | + Config.CROP_PAGE_WIDTH = response.page.rectangle.urx - response.page.rectangle.llx |
| 92 | + else: |
| 93 | + logging.error("Unexpected error : can't get pages!!!") |
| 94 | + |
| 95 | + def extractPdfPage(self, document: str, pageNumber: int, width: int, height: int, localFolder: str, tempFolder: str): |
| 96 | + if self.pdf_api: |
| 97 | + args = { |
| 98 | + "folder": tempFolder, |
| 99 | + "width": int(width), |
| 100 | + "height": int(height), |
| 101 | + } |
| 102 | + |
| 103 | + response = self.pdf_api.get_page_convert_to_png(document, pageNumber, **args) |
| 104 | + imageFile = document + ".png" |
| 105 | + imagePath = localFolder / imageFile |
| 106 | + shutil.move(response, str(imagePath)) |
| 107 | + |
| 108 | + self.uploadFile(imageFile, localFolder, tempFolder) |
| 109 | + |
| 110 | + logging.info(f"Page #{pageNumber} extracted as image.") |
| 111 | + return imageFile |
| 112 | + |
| 113 | + def createDocument(self, newDocumentName: str, width: int, height: int, tempFolder: Path): |
| 114 | + """ Create PDF document with required properties. """ |
| 115 | + if self.pdf_api: |
| 116 | + args = { |
| 117 | + "folder" : str(tempFolder) |
| 118 | + } |
| 119 | + |
| 120 | + document_config = DocumentConfig( |
| 121 | + pages_count = 1, |
| 122 | + document_properties=DocumentProperties( |
| 123 | + list=[ |
| 124 | + DocumentProperty( |
| 125 | + built_in=False, |
| 126 | + name='prop1', |
| 127 | + value='Val1', |
| 128 | + ) |
| 129 | + ]), |
| 130 | + display_properties=DisplayProperties( |
| 131 | + center_window = True, |
| 132 | + hide_menu_bar = True, |
| 133 | + ), |
| 134 | + default_page_config=DefaultPageConfig( |
| 135 | + height = height, |
| 136 | + width = width |
| 137 | + ), |
| 138 | + ) |
| 139 | + response = self.pdf_api.post_create_document(newDocumentName, document_config, **args) |
| 140 | + logging.info(f"Document #{newDocumentName} created.") |
| 141 | + return response |
| 142 | + |
| 143 | + def insertPageAsImage(self, document: str, imageFileValue: str, llx: int, lly: int, tempFolder: str): |
| 144 | + if self.pdf_api: |
| 145 | + args = { |
| 146 | + "folder" : str(tempFolder) |
| 147 | + } |
| 148 | + |
| 149 | + image_stamp: ImageStamp = ImageStamp( |
| 150 | + background = True, |
| 151 | + horizontal_alignment = HorizontalAlignment.NONE, |
| 152 | + vertical_alignment = VerticalAlignment.NONE, |
| 153 | + rotate = Rotation.NONE, |
| 154 | + rotate_angle = 0, |
| 155 | + opacity = 1, |
| 156 | + x_indent = -llx, |
| 157 | + y_indent = -lly, |
| 158 | + zoom = 1, |
| 159 | + file_name = os.path.join(tempFolder, imageFileValue) |
| 160 | + ) |
| 161 | + |
| 162 | + try: |
| 163 | + responseImageStamp: AsposeResponse = self.pdf_api.post_page_image_stamps(document, 1, [ image_stamp ], **args) |
| 164 | + if responseImageStamp.code != 200: |
| 165 | + logging.info( "Unexpected error on inserting image to the document!") |
| 166 | + else: |
| 167 | + return responseImageStamp |
| 168 | + |
| 169 | + except Exception as e: |
| 170 | + logging.error(f"add_document_stamps(): Failed to insert image: {e}") |
0 commit comments