From a04c7733c15d465e84276411c69e1d5c9a77a0c8 Mon Sep 17 00:00:00 2001 From: Dmitriy-Xawstov Date: Sun, 13 Jul 2025 21:25:00 +0300 Subject: [PATCH 1/5] PDFCLOUD-4775: added snippets for Annotations --- Uses-Cases/Annotations/annotations_helper.py | 97 +++++++++++++++++++ Uses-Cases/Annotations/annotations_launch.py | 37 +++++++ .../Annotations/delete_page_annotations.py | 25 +++++ .../Annotations/delete_text_annotation.py | 28 ++++++ Uses-Cases/Annotations/get_annotations.py | 42 ++++++++ .../Annotations/new_highlight_annotation.py | 47 +++++++++ .../Annotations/new_strikeout_annotation.py | 47 +++++++++ Uses-Cases/Annotations/new_text_annotation.py | 52 ++++++++++ .../Annotations/new_underline_annotation.py | 48 +++++++++ Uses-Cases/Annotations/replace_annotation.py | 39 ++++++++ 10 files changed, 462 insertions(+) create mode 100644 Uses-Cases/Annotations/annotations_helper.py create mode 100644 Uses-Cases/Annotations/annotations_launch.py create mode 100644 Uses-Cases/Annotations/delete_page_annotations.py create mode 100644 Uses-Cases/Annotations/delete_text_annotation.py create mode 100644 Uses-Cases/Annotations/get_annotations.py create mode 100644 Uses-Cases/Annotations/new_highlight_annotation.py create mode 100644 Uses-Cases/Annotations/new_strikeout_annotation.py create mode 100644 Uses-Cases/Annotations/new_text_annotation.py create mode 100644 Uses-Cases/Annotations/new_underline_annotation.py create mode 100644 Uses-Cases/Annotations/replace_annotation.py diff --git a/Uses-Cases/Annotations/annotations_helper.py b/Uses-Cases/Annotations/annotations_helper.py new file mode 100644 index 0000000..2869d6d --- /dev/null +++ b/Uses-Cases/Annotations/annotations_helper.py @@ -0,0 +1,97 @@ +import shutil +import json +import logging +import os +from pathlib import Path +from asposepdfcloud import ApiClient, PdfApi, HighlightAnnotation, Rectangle, Color, Point, AnnotationFlags, HorizontalAlignment, VerticalAlignment, AnnotationType + +# Configure logging +logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") + + +class Config: + """Configuration parameters.""" + CREDENTIALS_FILE = Path(r"C:\\Projects\\ASPOSE\\Pdf.Cloud\\Credentials\\credentials.json") + LOCAL_FOLDER = Path(r"C:\Samples") + REMOTE_FOLDER = "Your_Temp_Pdf_Cloud" + PDF_DOCUMENT_NAME = "sample.pdf" + LOCAL_RESULT_DOCUMENT_NAME = "output_sample.pdf" + PAGE_NUMBER = 1 + + ANNOTATION_ID = "GE5TAOZTHA2CYMRZGUWDIMBZFQZTEMA" + + NEW_HL_ANNOTATION_TEXT = "NEW HIGHLIGHT TEXT ANNOTATION" + NEW_HL_ANNOTATION_DESCRIPTION = 'This is a sample highlight annotation' + NEW_HL_ANNOTATION_SUBJECT = "Highlight Text Box Subject" + NEW_HL_ANNOTATION_CONTENTS = "Highlight annotation sample contents" + + NEW_SO_ANNOTATION_TEXT = "NEW STRIKEOUT TEXT ANNOTATION" + NEW_SO_ANNOTATION_DESCRIPTION = 'This is a sample strikeout annotation' + NEW_SO_ANNOTATION_SUBJECT = "Strikeout Text Box Subject" + NEW_SO_ANNOTATION_CONTENTS = "Strikeout annotation sample contents" + + NEW_UL_ANNOTATION_TEXT = "NEW UNDERLINE TEXT ANNOTATION" + NEW_UL_ANNOTATION_DESCRIPTION = 'This is a sample underline annotation' + NEW_UL_ANNOTATION_SUBJECT = "Underline Text Box Subject" + NEW_UL_ANNOTATION_CONTENTS = "Underline annotation sample contents" + + NEW_FT_ANNOTATION_TEXT = "NEW FREE TEXT ANNOTATION" + NEW_FT_ANNOTATION_DESCRIPTION = 'This is a sample annotation' + NEW_FT_ANNOTATION_SUBJECT = "Free Text Box Subject" + NEW_FT_ANNOTATION_CONTENTS = "Free Text annotation sample contents" + + REPLACED_CONTENT = 'This is a replaced sample annotation' + +class PdfAnnotationsHelper: + def __init__(self, credentials_file: Path): + self.pdf_api = None + self._init_api(credentials_file) + + def _init_api(self, credentials_file: Path): + """Initialize the API client.""" + try: + with credentials_file.open("r", encoding="utf-8") as file: + credentials = json.load(file) + api_key, app_id = credentials.get("key"), credentials.get("id") + if not api_key or not app_id: + raise ValueError("Error: Missing API keys in the credentials file.") + self.pdf_api = PdfApi(ApiClient(api_key, app_id)) + except (FileNotFoundError, json.JSONDecodeError, ValueError) as e: + logging.error(f"Failed to load credentials: {e}") + + def uploadFile(self, fileName: str, localFolder: Path, remoteFolder: str): + """ Upload a local fileName to the Aspose Cloud server. """ + if self.pdf_api: + file_path = localFolder / fileName + try: + self.pdf_api.upload_file(os.path.join(remoteFolder, fileName), file_path) + logging.info(f"upload_file(): File '{fileName}' uploaded successfully.") + except Exception as e: + logging.error(f"upload_document(): Failed to upload file: {e}") + + + def downloadFile(self, document: str, outputDocument: str, localFolder: Path, remoteFolder: Path, output_prefix: str): + """Download the processed PDF document from the Aspose Cloud server.""" + if self.pdf_api: + try: + temp_file = self.pdf_api.download_file(str(remoteFolder) + '/' + document) + local_path = localFolder / ( output_prefix + outputDocument ) + shutil.move(temp_file, str(local_path)) + logging.info(f"download_result(): File successfully downloaded: {local_path}") + except Exception as e: + logging.error(f"download_result(): Failed to download file: {e}") + + def delete_popup_annotations(self, parent_annotation): + """delete popup annotations for typed parent annotation in the page in the PDF document.""" + if self.pdf_api: + args = { + "folder": Config.REMOTE_FOLDER + } + response = self.pdf_api.get_document_popup_annotations(Config.PDF_DOCUMENT_NAME, **args) + if response.code == 200: + for annotation in response.annotations.list: + if annotation.parent.id == parent_annotation: + self.pdf_api.delete_annotation(Config.PDF_DOCUMENT_NAME, annotation.id, **args) + logging.info(f"delete_popup_annotations(): popup annotation id = '{annotation.id}' for '{annotation.contents}' deleted in the document '{Config.PDF_DOCUMENT_NAME}'.") + else: + logging.error(f"delete_popup_annotations(): Failed to delete popup annotation in the document. Response code: {response.code}") \ No newline at end of file diff --git a/Uses-Cases/Annotations/annotations_launch.py b/Uses-Cases/Annotations/annotations_launch.py new file mode 100644 index 0000000..24fb2ab --- /dev/null +++ b/Uses-Cases/Annotations/annotations_launch.py @@ -0,0 +1,37 @@ +from annotations_helper import PdfAnnotationsHelper, Config +from get_annotations import PdfGetAnnotations +from new_highlight_annotation import PdfAddHighlightAnnotations +from new_strikeout_annotation import PdfAddStrikeoutAnnotations +from new_text_annotation import PdfAddFreeTextAnnotations +from new_underline_annotation import PdfAddUnderlineAnnotations +from delete_page_annotations import PdfDelPageAnnotations +from delete_text_annotation import PdfDalTextAnnotations +from replace_annotation import PdfReplaceAnnotations + +if __name__ == "__main__": + helper = PdfAnnotationsHelper(Config.CREDENTIALS_FILE) + + modify_ant = PdfReplaceAnnotations(helper.pdf_api, helper) + modify_ant.modify_annotation() + + get_ant = PdfGetAnnotations(helper.pdf_api, helper) + annotation_id =get_ant.get_annotations() + get_ant.get_annotation(annotation_id) + + del_ant = PdfDalTextAnnotations(helper.pdf_api, helper) + del_ant.delete_annotation() + + del_page_ant = PdfDelPageAnnotations(helper.pdf_api, helper) + del_page_ant.delete_page_annotations() + + add_hl = PdfAddHighlightAnnotations(helper.pdf_api, helper) + add_hl.append_highlight_annotation() + + add_so = PdfAddStrikeoutAnnotations(helper.pdf_api, helper) + add_so.append_strikeout_annotation() + + add_ft = PdfAddFreeTextAnnotations(helper.pdf_api, helper) + add_ft.append_text_annotation() + + add_ul = PdfAddUnderlineAnnotations(helper.pdf_api, helper) + add_ul.append_underline_annotation() \ No newline at end of file diff --git a/Uses-Cases/Annotations/delete_page_annotations.py b/Uses-Cases/Annotations/delete_page_annotations.py new file mode 100644 index 0000000..0edb053 --- /dev/null +++ b/Uses-Cases/Annotations/delete_page_annotations.py @@ -0,0 +1,25 @@ + +from annotations_helper import Config, PdfAnnotationsHelper, logging +from asposepdfcloud import PdfApi + +class PdfDelPageAnnotations: + """Class for managing PDF annotations using Aspose PDF Cloud API.""" + def __init__(self, pdf_api: PdfApi, helper: PdfAnnotationsHelper): + self.pdfApi = pdf_api + self.helper = helper + + def delete_page_annotations(self): + """Delete annotation from the PDF document.""" + if self.pdfApi: + self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) + + args = { + "folder": Config.REMOTE_FOLDER + } + + response = self.pdfApi.delete_page_annotations(Config.PDF_DOCUMENT_NAME, Config.PAGE_NUMBER, **args) + if response.code == 200: + logging.info(f"delete_annotation(): annotations on page '{Config.PAGE_NUMBER}' deleted from the document '{Config.PDF_DOCUMENT_NAME}'.") + self.helper.downloadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_RESULT_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER, "del_page_annotations_") + else: + logging.error(f"delete_annotation(): Failed to delete annotation from the document. Response code: {response.code}") \ No newline at end of file diff --git a/Uses-Cases/Annotations/delete_text_annotation.py b/Uses-Cases/Annotations/delete_text_annotation.py new file mode 100644 index 0000000..cb0c4ec --- /dev/null +++ b/Uses-Cases/Annotations/delete_text_annotation.py @@ -0,0 +1,28 @@ + +from annotations_helper import Config, PdfAnnotationsHelper, logging +from asposepdfcloud import PdfApi + +class PdfDalTextAnnotations: + """Class for managing PDF annotations using Aspose PDF Cloud API.""" + def __init__(self, pdf_api: PdfApi, helper: PdfAnnotationsHelper): + self.pdfApi = pdf_api + self.helper = helper + + def delete_annotation(self): + """Delete annotation from the PDF document.""" + if self.pdfApi: + if Config.ANNOTATION_ID is None: + logging.info(f"delete_annotation(): annotation id not defined!") + return + self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) + + args = { + "folder": Config.REMOTE_FOLDER + } + response = self.pdfApi.delete_annotation(Config.PDF_DOCUMENT_NAME, Config.ANNOTATION_ID, **args) + self.helper.delete_popup_annotations(Config.ANNOTATION_ID) + if response.code == 200: + logging.info(f"delete_annotation(): annotation '{Config.ANNOTATION_ID}' deleted from the document '{Config.PDF_DOCUMENT_NAME}'.") + self.helper.downloadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_RESULT_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER, "del_annotation_") + else: + logging.error(f"delete_annotation(): Failed to delete annotation from the document. Response code: {response.code}") \ No newline at end of file diff --git a/Uses-Cases/Annotations/get_annotations.py b/Uses-Cases/Annotations/get_annotations.py new file mode 100644 index 0000000..71f00db --- /dev/null +++ b/Uses-Cases/Annotations/get_annotations.py @@ -0,0 +1,42 @@ +from annotations_helper import Config, PdfAnnotationsHelper, logging +from asposepdfcloud import PdfApi, AnnotationsInfoResponse + +class PdfGetAnnotations: + """Class for managing PDF annotations using Aspose PDF Cloud API.""" + def __init__(self, pdf_api: PdfApi, helper: PdfAnnotationsHelper): + self.pdfApi = pdf_api + self.helper = helper + + def get_annotations(self): + """Get annotations from the page in the PDF document.""" + if self.pdfApi: + self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) + + args = { + "folder": Config.REMOTE_FOLDER + } + annotation_result = '' + response: AnnotationsInfoResponse = self.pdfApi.get_page_annotations(Config.PDF_DOCUMENT_NAME, Config.PAGE_NUMBER, **args) + if response.code == 200: + for annotation in response.annotations.list: + if annotation.annotation_type == "Text": + logging.info(f"get_annotations(): annotation id={annotation.id} with '{annotation.contents}' content get from the document '{Config.PDF_DOCUMENT_NAME}' on {annotation.page_index} page.") + annotation_result = annotation.id + return annotation_result + else: + logging.error(f"get_annotations(): Failed to get annotation in the document. Response code: {response.code}") + return annotation_result + + def get_annotation(self, annotation_id): + """Get annotation from the page in the PDF document.""" + if self.pdfApi: + self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) + + args = { + "folder": Config.REMOTE_FOLDER + } + response = self.pdfApi.get_text_annotation(Config.PDF_DOCUMENT_NAME, annotation_id, **args) + if response.code == 200: + logging.info(f"get_annotationn(): annotation '{annotation_id}' successfully found '{response.annotation.contents}' in the document '{Config.PDF_DOCUMENT_NAME}'.") + else: + logging.error(f"get_annotation(): Failed to get annotation in the document. Response code: {response.code}") \ No newline at end of file diff --git a/Uses-Cases/Annotations/new_highlight_annotation.py b/Uses-Cases/Annotations/new_highlight_annotation.py new file mode 100644 index 0000000..3ece7c1 --- /dev/null +++ b/Uses-Cases/Annotations/new_highlight_annotation.py @@ -0,0 +1,47 @@ +from annotations_helper import Config, PdfAnnotationsHelper, logging +from asposepdfcloud import PdfApi, HighlightAnnotation, Rectangle, Color, Point, AnnotationFlags, HorizontalAlignment, VerticalAlignment + +class PdfAddHighlightAnnotations: + """Class for managing PDF annotations using Aspose PDF Cloud API.""" + def __init__(self, pdf_api: PdfApi, helper: PdfAnnotationsHelper): + self.pdfApi = pdf_api + self.helper = helper + + def append_highlight_annotation(self): + """Append a new highlight text annotation to the PDF document.""" + if self.pdfApi: + self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) + + args = { + "folder": Config.REMOTE_FOLDER + } + + new_annotation = HighlightAnnotation( + rect = Rectangle(llx=100, lly=350, urx=450, ury=400), + name = 'Highlight_Text_Annotation', + flags = [AnnotationFlags.DEFAULT], + horizontal_alignment = HorizontalAlignment.LEFT, + vertical_alignment = VerticalAlignment.TOP, + rich_text = Config.NEW_HL_ANNOTATION_TEXT, + subject = Config.NEW_HL_ANNOTATION_SUBJECT, + contents= Config.NEW_HL_ANNOTATION_CONTENTS, + title = Config.NEW_HL_ANNOTATION_DESCRIPTION, + z_index = 1, + color=Color(a=0xFF, r=0, g=0xFF, b=0), + quad_points = [ + Point(10, 10), + Point(20, 10), + Point(10, 20), + Point(10, 10) + ], + modified = '03/27/2025 00:00:00.000 AM', + ) + try: + response = self.pdfApi.post_page_highlight_annotations(Config.PDF_DOCUMENT_NAME, Config.PAGE_NUMBER, [new_annotation], **args) + if response.code == 200: + logging.info(f"append_highlight_annotation(): annotation '{Config.NEW_HL_ANNOTATION_TEXT}' added to the document '{Config.PDF_DOCUMENT_NAME}'.") + self.helper.downloadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_RESULT_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER, "add_highlight_") + else: + logging.error(f"append_highlight_annotation(): Failed to add annotation to the document. Response code: {response.code}") + except Exception as e: + logging.error(f"append_highlight_annotation(): Error while adding annotation: {e}") \ No newline at end of file diff --git a/Uses-Cases/Annotations/new_strikeout_annotation.py b/Uses-Cases/Annotations/new_strikeout_annotation.py new file mode 100644 index 0000000..0d217de --- /dev/null +++ b/Uses-Cases/Annotations/new_strikeout_annotation.py @@ -0,0 +1,47 @@ +from annotations_helper import Config, PdfAnnotationsHelper, logging +from asposepdfcloud import PdfApi, StrikeOutAnnotation, Rectangle, Color, Point, AnnotationFlags, HorizontalAlignment, VerticalAlignment + +class PdfAddStrikeoutAnnotations: + """Class for managing PDF annotations using Aspose PDF Cloud API.""" + def __init__(self, pdf_api: PdfApi, helper: PdfAnnotationsHelper): + self.pdfApi = pdf_api + self.helper = helper + + def append_strikeout_annotation(self): + """Append a new strikeout text annotation to the PDF document.""" + if self.pdfApi: + self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) + + args = { + "folder": Config.REMOTE_FOLDER + } + + new_annotation = StrikeOutAnnotation( + rect = Rectangle(llx=100, lly=100, urx=200, ury=200), + name = 'Strikeout_Text_Annotation', + flags = [AnnotationFlags.DEFAULT], + horizontal_alignment = HorizontalAlignment.LEFT, + vertical_alignment = VerticalAlignment.TOP, + rich_text = Config.NEW_SO_ANNOTATION_TEXT, + subject = Config.NEW_SO_ANNOTATION_SUBJECT, + title = Config.NEW_SO_ANNOTATION_DESCRIPTION, + contents= Config.NEW_SO_ANNOTATION_CONTENTS, + z_index = 1, + color= Color(a=0xFF, r=0, g=0xFF, b=0), + quad_points = [ + Point(10, 10), + Point(20, 10), + Point(10, 20), + Point(10, 10) + ], + modified = '03/27/2025 00:00:00.000 AM', + ) + try: + response = self.pdfApi.post_page_strike_out_annotations(Config.PDF_DOCUMENT_NAME, Config.PAGE_NUMBER, [new_annotation], **args) + if response.code == 200: + logging.info(f"append_strikeout_annotation(): annotation '{Config.NEW_SO_ANNOTATION_TEXT}' added to the document '{Config.PDF_DOCUMENT_NAME}'.") + self.helper.downloadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_RESULT_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER, "add_strikeout_") + else: + logging.error(f"append_strikeout_annotation(): Failed to add annotation to the document. Response code: {response.code}") + except Exception as e: + logging.error(f"append_strikeout_annotation(): Error while adding annotation: {e}") \ No newline at end of file diff --git a/Uses-Cases/Annotations/new_text_annotation.py b/Uses-Cases/Annotations/new_text_annotation.py new file mode 100644 index 0000000..2f1fda4 --- /dev/null +++ b/Uses-Cases/Annotations/new_text_annotation.py @@ -0,0 +1,52 @@ +from annotations_helper import Config, PdfAnnotationsHelper, logging +from asposepdfcloud import ApiClient, PdfApi, FreeTextAnnotation, Rectangle, TextStyle, Color, FreeTextIntent, Justification, AnnotationFlags, HorizontalAlignment + +class PdfAddFreeTextAnnotations: + """Class for managing PDF annotations using Aspose PDF Cloud API.""" + def __init__(self, pdf_api: PdfApi, helper: PdfAnnotationsHelper): + self.pdfApi = pdf_api + self.helper = helper + + def append_text_annotation(self): + """Append a new free text annotation to the PDF document.""" + if self.pdfApi: + self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) + + args = { + "folder": Config.REMOTE_FOLDER + } + + text_style = TextStyle( + font_size=20, + font='Arial', + foreground_color=Color(a=0xFF, r=0, g=0xFF, b=0), + background_color=Color(a=0xFF, r=0xFF, g=0, b=0) + ) + + new_annotation = FreeTextAnnotation( + rect = Rectangle(llx=100, lly=350, urx=450, ury=400), + text_style = text_style, + name = 'Free Text Annotation', + flags = [AnnotationFlags.DEFAULT], + horizontal_alignment = HorizontalAlignment.CENTER, + intent = FreeTextIntent.FREETEXTTYPEWRITER, + rich_text = Config.NEW_FT_ANNOTATION_TEXT, + subject = Config.NEW_FT_ANNOTATION_SUBJECT, + contents = Config.NEW_FT_ANNOTATION_CONTENTS, + title = Config.NEW_FT_ANNOTATION_DESCRIPTION, + z_index = 1, + justification = Justification.CENTER, + ) + new_annotation.attribute_map["icon"] = "Icon" + new_annotation.swagger_types["icon"] = "TextIcon" + new_annotation.icon = "Help" + + try: + response = self.pdfApi.post_page_free_text_annotations(Config.PDF_DOCUMENT_NAME, Config.PAGE_NUMBER, [new_annotation], **args) + if response.code == 200: + logging.info(f"append_text_annotation(): annotation '{Config.NEW_FT_ANNOTATION_TEXT}' added to the document '{Config.PDF_DOCUMENT_NAME}'.") + self.helper.downloadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_RESULT_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER, "add_freetext_") + else: + logging.error(f"append_text_annotation(): Failed to add annotation to the document. Response code: {response.code}") + except Exception as e: + logging.error(f"append_text_annotation(): Error while adding annotation: {e}") \ No newline at end of file diff --git a/Uses-Cases/Annotations/new_underline_annotation.py b/Uses-Cases/Annotations/new_underline_annotation.py new file mode 100644 index 0000000..f2c5364 --- /dev/null +++ b/Uses-Cases/Annotations/new_underline_annotation.py @@ -0,0 +1,48 @@ +from annotations_helper import Config, PdfAnnotationsHelper, logging +from asposepdfcloud import ApiClient, PdfApi, UnderlineAnnotation, Rectangle, Color, Point, AnnotationFlags, HorizontalAlignment, VerticalAlignment,AnnotationState + +class PdfAddUnderlineAnnotations: + """Class for managing PDF annotations using Aspose PDF Cloud API.""" + def __init__(self, pdf_api: PdfApi, helper: PdfAnnotationsHelper): + self.pdfApi = pdf_api + self.helper = helper + + def append_underline_annotation(self): + """Append a new underline text annotation to the PDF document.""" + if self.pdfApi: + self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) + args = { + "folder": Config.REMOTE_FOLDER + } + new_annotation = UnderlineAnnotation( + rect = Rectangle(llx=100, lly=350, urx=450, ury=400), + name = 'Underline Text Annotation', + flags = [AnnotationFlags.DEFAULT], + horizontal_alignment = HorizontalAlignment.CENTER, + vertical_alignment = VerticalAlignment.TOP, + rich_text = Config.NEW_UL_ANNOTATION_TEXT, + subject = Config.NEW_UL_ANNOTATION_SUBJECT, + title = Config.NEW_UL_ANNOTATION_DESCRIPTION, + contents= Config.NEW_UL_ANNOTATION_CONTENTS, + z_index = 1, + color=Color(a=0xFF, r=0, g=0xFF, b=0), + quad_points = [ + Point(10, 10), + Point(20, 10), + Point(10, 20), + Point(10, 10) + ], + modified = '03/27/2025 00:00:00.000 AM', + ) + new_annotation.attribute_map["icon"] = "Icon" + new_annotation.swagger_types["icon"] = "TextIcon" + new_annotation.icon = "Star" + try: + response = self.pdfApi.post_page_underline_annotations(Config.PDF_DOCUMENT_NAME, Config.PAGE_NUMBER, [new_annotation], **args) + if response.code == 200: + logging.info(f"append_underline_annotation(): annotation '{Config.NEW_UL_ANNOTATION_TEXT}' added to the document '{Config.PDF_DOCUMENT_NAME}'.") + self.helper.downloadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_RESULT_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER, "add_underline_") + else: + logging.error(f"append_underline_annotation(): Failed to add annotation to the document. Response code: {response.code}") + except Exception as e: + logging.error(f"append_underline_annotation(): Error while adding annotation: {e}") \ No newline at end of file diff --git a/Uses-Cases/Annotations/replace_annotation.py b/Uses-Cases/Annotations/replace_annotation.py new file mode 100644 index 0000000..ef05ae6 --- /dev/null +++ b/Uses-Cases/Annotations/replace_annotation.py @@ -0,0 +1,39 @@ +from annotations_helper import Config, PdfAnnotationsHelper, logging +from asposepdfcloud import PdfApi, TextAnnotationResponse + +class PdfReplaceAnnotations: + """Class for managing PDF annotations using Aspose PDF Cloud API.""" + def __init__(self, pdf_api: PdfApi, helper: PdfAnnotationsHelper): + self.pdfApi = pdf_api + self.helper = helper + + def _get_annotation(self, annotation_id): + """Get annotation from the page in the PDF document.""" + if self.pdfApi: + args = { + "folder": Config.REMOTE_FOLDER + } + response: TextAnnotationResponse = self.pdfApi.get_text_annotation(Config.PDF_DOCUMENT_NAME, annotation_id, **args) + if response.code == 200: + logging.info(f"get_annotationn(): annotation '{annotation_id}' successfully found '{response.annotation.contents}' in the document '{Config.PDF_DOCUMENT_NAME}'.") + return response.annotation + else: + logging.error(f"get_annotation(): Failed to get annotation in the document. Response code: {response.code}") + return None + + def modify_annotation(self): + if self.pdfApi: + if Config.ANNOTATION_ID: + self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) + args = { + "folder": Config.REMOTE_FOLDER + } + annotation = self._get_annotation(Config.ANNOTATION_ID) + annotation.contents = Config.REPLACED_CONTENT + annotation.icon = "Star" + response = self.pdfApi.put_text_annotation(Config.PDF_DOCUMENT_NAME, Config.ANNOTATION_ID, annotation, **args) + if response.code == 200: + logging.info(f"modify_annotation(): annotation '{annotation.id}' successfully modified in the document '{Config.PDF_DOCUMENT_NAME}'.") + self.helper.downloadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_RESULT_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER, "replaced_annotatiom_") + else: + logging.error(f"modify_annotation(): Failed to modify annotation in the document. Response code: {response.code}") \ No newline at end of file From 5511b1a3f4c81484c05e72562da4440128aa560c Mon Sep 17 00:00:00 2001 From: Dmitriy-Xawstov Date: Sun, 13 Jul 2025 21:26:29 +0300 Subject: [PATCH 2/5] Update annotations_helper.py --- Uses-Cases/Annotations/annotations_helper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Uses-Cases/Annotations/annotations_helper.py b/Uses-Cases/Annotations/annotations_helper.py index 2869d6d..a750fc8 100644 --- a/Uses-Cases/Annotations/annotations_helper.py +++ b/Uses-Cases/Annotations/annotations_helper.py @@ -11,7 +11,7 @@ class Config: """Configuration parameters.""" - CREDENTIALS_FILE = Path(r"C:\\Projects\\ASPOSE\\Pdf.Cloud\\Credentials\\credentials.json") + CREDENTIALS_FILE = Path(r".\credentials.json") LOCAL_FOLDER = Path(r"C:\Samples") REMOTE_FOLDER = "Your_Temp_Pdf_Cloud" PDF_DOCUMENT_NAME = "sample.pdf" @@ -94,4 +94,4 @@ def delete_popup_annotations(self, parent_annotation): self.pdf_api.delete_annotation(Config.PDF_DOCUMENT_NAME, annotation.id, **args) logging.info(f"delete_popup_annotations(): popup annotation id = '{annotation.id}' for '{annotation.contents}' deleted in the document '{Config.PDF_DOCUMENT_NAME}'.") else: - logging.error(f"delete_popup_annotations(): Failed to delete popup annotation in the document. Response code: {response.code}") \ No newline at end of file + logging.error(f"delete_popup_annotations(): Failed to delete popup annotation in the document. Response code: {response.code}") From c0aead5d08e8c26f53908f77918022a624cdee61 Mon Sep 17 00:00:00 2001 From: Dmitriy-Xawstov Date: Thu, 17 Jul 2025 22:43:35 +0300 Subject: [PATCH 3/5] Update annotations_launch.py --- Uses-Cases/Annotations/annotations_launch.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Uses-Cases/Annotations/annotations_launch.py b/Uses-Cases/Annotations/annotations_launch.py index 24fb2ab..9729b7d 100644 --- a/Uses-Cases/Annotations/annotations_launch.py +++ b/Uses-Cases/Annotations/annotations_launch.py @@ -1,5 +1,6 @@ from annotations_helper import PdfAnnotationsHelper, Config from get_annotations import PdfGetAnnotations +from get_annotation_by_id import PdfGetAnnotationById from new_highlight_annotation import PdfAddHighlightAnnotations from new_strikeout_annotation import PdfAddStrikeoutAnnotations from new_text_annotation import PdfAddFreeTextAnnotations @@ -15,8 +16,10 @@ modify_ant.modify_annotation() get_ant = PdfGetAnnotations(helper.pdf_api, helper) - annotation_id =get_ant.get_annotations() - get_ant.get_annotation(annotation_id) + annotation_id =get_ant.request_annotations() + + rq_ant = PdfGetAnnotationById(helper.pdf_api, helper) + rq_ant.request_annotation(annotation_id) del_ant = PdfDalTextAnnotations(helper.pdf_api, helper) del_ant.delete_annotation() @@ -34,4 +37,4 @@ add_ft.append_text_annotation() add_ul = PdfAddUnderlineAnnotations(helper.pdf_api, helper) - add_ul.append_underline_annotation() \ No newline at end of file + add_ul.append_underline_annotation() From f7c55683933b6c677aade0ca00e9b5bff7d0c658 Mon Sep 17 00:00:00 2001 From: Dmitriy-Xawstov Date: Thu, 17 Jul 2025 22:44:29 +0300 Subject: [PATCH 4/5] Update get_annotations.py --- Uses-Cases/Annotations/get_annotations.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/Uses-Cases/Annotations/get_annotations.py b/Uses-Cases/Annotations/get_annotations.py index 71f00db..1633b2c 100644 --- a/Uses-Cases/Annotations/get_annotations.py +++ b/Uses-Cases/Annotations/get_annotations.py @@ -7,7 +7,7 @@ def __init__(self, pdf_api: PdfApi, helper: PdfAnnotationsHelper): self.pdfApi = pdf_api self.helper = helper - def get_annotations(self): + def request_annotations(self): """Get annotations from the page in the PDF document.""" if self.pdfApi: self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) @@ -26,17 +26,3 @@ def get_annotations(self): else: logging.error(f"get_annotations(): Failed to get annotation in the document. Response code: {response.code}") return annotation_result - - def get_annotation(self, annotation_id): - """Get annotation from the page in the PDF document.""" - if self.pdfApi: - self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) - - args = { - "folder": Config.REMOTE_FOLDER - } - response = self.pdfApi.get_text_annotation(Config.PDF_DOCUMENT_NAME, annotation_id, **args) - if response.code == 200: - logging.info(f"get_annotationn(): annotation '{annotation_id}' successfully found '{response.annotation.contents}' in the document '{Config.PDF_DOCUMENT_NAME}'.") - else: - logging.error(f"get_annotation(): Failed to get annotation in the document. Response code: {response.code}") \ No newline at end of file From afb378a4d3b2ce8f49ea5012ca7aec7ce851fd85 Mon Sep 17 00:00:00 2001 From: Dmitriy-Xawstov Date: Thu, 17 Jul 2025 22:45:27 +0300 Subject: [PATCH 5/5] Add files via upload --- .../Annotations/get_annotation_by_id.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Uses-Cases/Annotations/get_annotation_by_id.py diff --git a/Uses-Cases/Annotations/get_annotation_by_id.py b/Uses-Cases/Annotations/get_annotation_by_id.py new file mode 100644 index 0000000..458a14c --- /dev/null +++ b/Uses-Cases/Annotations/get_annotation_by_id.py @@ -0,0 +1,22 @@ +from annotations_helper import Config, PdfAnnotationsHelper, logging +from asposepdfcloud import PdfApi, AnnotationsInfoResponse + +class PdfGetAnnotationById: + """Class for managing PDF annotations using Aspose PDF Cloud API.""" + def __init__(self, pdf_api: PdfApi, helper: PdfAnnotationsHelper): + self.pdfApi = pdf_api + self.helper = helper + + def request_annotation(self, annotation_id): + """Get annotation from the page in the PDF document.""" + if self.pdfApi: + self.helper.uploadFile(Config.PDF_DOCUMENT_NAME, Config.LOCAL_FOLDER, Config.REMOTE_FOLDER) + + args = { + "folder": Config.REMOTE_FOLDER + } + response = self.pdfApi.get_text_annotation(Config.PDF_DOCUMENT_NAME, annotation_id, **args) + if response.code == 200: + logging.info(f"get_annotationn(): annotation '{annotation_id}' successfully found '{response.annotation.contents}' in the document '{Config.PDF_DOCUMENT_NAME}'.") + else: + logging.error(f"get_annotation(): Failed to get annotation in the document. Response code: {response.code}") \ No newline at end of file