From ce51d16bb33ebd8c960f622fd588d93b7e94c70b Mon Sep 17 00:00:00 2001 From: Timothyxxx <384084775@qq.com> Date: Mon, 22 Jan 2024 02:41:17 +0800 Subject: [PATCH] Loading Impress v1 batch --- desktop_env/evaluators/metrics/__init__.py | 5 +- desktop_env/evaluators/metrics/impress.py | 122 +++++++++++++----- .../455d3c66-7dc6-4537-a39a-36d3e9119df7.json | 14 +- .../550ce7e7-747b-495f-b122-acdc4d0b8e54.json | 10 +- .../5d901039-a89c-4bfb-967b-bf66f4df075e.json | 8 +- .../ac9bb6cb-1888-43ab-81e4-a98a547918cd.json | 2 +- .../af23762e-2bfd-4a1d-aada-20fa8de9ce07.json | 2 +- .../59f21cfb-0120-4326-b255-a5b827b38967.json | 2 +- 8 files changed, 121 insertions(+), 44 deletions(-) diff --git a/desktop_env/evaluators/metrics/__init__.py b/desktop_env/evaluators/metrics/__init__.py index 0d7c9cc..23e9a7e 100644 --- a/desktop_env/evaluators/metrics/__init__.py +++ b/desktop_env/evaluators/metrics/__init__.py @@ -14,5 +14,6 @@ from .gimp import increase_saturation, decrease_brightness, check_file_exists, c from .general import check_csv, check_accessibility_tree, check_list, run_sqlite3, check_json from .thunderbird import check_thunderbird_prefs, check_thunderbird_filter from .vscode import compare_text_file, compare_config, compare_answer, is_extension_installed -from .impress import check_slide_numbers_color, compare_pptx_files, check_for_two_lines, check_for_audio, check_formula_shape, check_file_exists -from .impress import check_slide_orientation_Portrait, contains_mp4_video \ No newline at end of file +from .impress import check_image_stretch_and_center, check_slide_numbers_color, compare_pptx_files, check_strikethrough, \ + check_for_audio, check_formula_shape +from .impress import check_slide_orientation_Portrait, contains_mp4_video diff --git a/desktop_env/evaluators/metrics/impress.py b/desktop_env/evaluators/metrics/impress.py index 749bc0e..b68a6fe 100644 --- a/desktop_env/evaluators/metrics/impress.py +++ b/desktop_env/evaluators/metrics/impress.py @@ -1,24 +1,56 @@ from pptx import Presentation -import os +from pptx.util import Inches + + +def check_image_stretch_and_center(modified_ppt, original_ppt): + # fixme: this func is overfit to this example libreoffice_impress + # Load the presentations + original_pres = Presentation(original_ppt) + modified_pres = Presentation(modified_ppt) + + # Get the first slide of each presentation + original_slide = original_pres.slides[0] + modified_slide = modified_pres.slides[0] + + # Get the image on the first slide of each presentation + original_slide_images = [shape for shape in original_slide.shapes if shape.shape_type == 13] + modified_slide_images = [shape for shape in modified_slide.shapes if shape.shape_type == 13] + + the_image = original_slide_images[0] + + # Get the images that modified in width and height + for modified_image in modified_slide_images: + if the_image.image.blob == modified_image.image.blob: + the_modified_image = modified_image + + if (abs(the_modified_image.width - original_pres.slide_width) > Inches(0.1) or + abs(the_modified_image.height - original_pres.slide_height) > Inches(0.1) or + abs(the_modified_image.left - (original_pres.slide_width - the_modified_image.width) / 2) > Inches(0.1) or + abs(the_modified_image.top - (original_pres.slide_height - the_modified_image.height) / 2) > Inches(0.1)): + return False + + return True + def is_red_color(color): - #judge if the color is red + # judge if the color is red print(color.rgb) return color and color.rgb == (255, 0, 0) + def get_master_placeholder_color(prs): # get the color of the placeholder masters = prs.slide_masters for idx, master in enumerate(masters): - for placeholder in master.placeholders: - if placeholder.has_text_frame and placeholder.text == "": + for placeholder in master.placeholders: + if placeholder.has_text_frame and placeholder.text == "": text_frame = placeholder.text_frame if text_frame.paragraphs: first_paragraph = text_frame.paragraphs[0] - return first_paragraph.font.color - return None - + return first_paragraph.font.color + return None + def check_slide_numbers_color(pptx_file_path): presentation = Presentation(pptx_file_path) @@ -34,42 +66,65 @@ def check_slide_numbers_color(pptx_file_path): print(font_color) return 1 if font_color is not None and is_red_color(font_color) else 0 -def compare_pptx_files(file1_path, file2_path): + +def compare_pptx_files(file1_path, file2_path, **options): + # todo: not strictly match since not all information is compared because we cannot get the info through pptx prs1 = Presentation(file1_path) prs2 = Presentation(file2_path) # compare the number of slides if len(prs1.slides) != len(prs2.slides): - return 0 + return False # compare the content of each slide for slide1, slide2 in zip(prs1.slides, prs2.slides): # check if the shapes are the same for shape1, shape2 in zip(slide1.shapes, slide2.shapes): + if shape1.left != shape2.left or shape1.top != shape2.top or shape1.width != shape2.width or shape1.height != shape2.height: + return False + if hasattr(shape1, "text") and hasattr(shape2, "text"): if shape1.text != shape2.text: - return 0 - return 1 + return False -def has_two_lines_on_page(slide): - line_count = 0 - for shape in slide.shapes: - if shape.shape_type == 1: # 1 表示 Line 形状 - line_count += 1 - if line_count >= 2: - return True - return False + # check if the paragraphs are the same + for para1, para2 in zip(shape1.text_frame.paragraphs, shape2.text_frame.paragraphs): + # check if the runs are the same + for run1, run2 in zip(para1.runs, para2.runs): + if run1.text != run2.text: + return False -def check_for_two_lines(prs): - prs = Presentation(prs) - for i, slide in enumerate(prs.slides): - if has_two_lines_on_page(slide): - return 1 - return 0 + # check if the font properties are the same + if run1.font.name != run2.font.name or run1.font.size != run2.font.size or run1.font.bold != run2.font.bold or run1.font.italic != run2.font.italic or run1.font.color.rgb != run2.font.color.rgb: + return False + + return True + + +def check_strikethrough(pptx_path, rules): + # Load the presentation + presentation = Presentation(pptx_path) + + slide_index_s = rules["slide_index_s"] + shape_index_s = rules["shape_index_s"] + paragraph_index_s = rules["paragraph_index_s"] + + for slide_index in slide_index_s: + # Get the slide + slide = presentation.slides[slide_index] + + for shape_index in shape_index_s: + # Get the text box + paragraphs = slide.shapes[shape_index].text_frame.paragraphs + + for paragraph_index in paragraph_index_s: + paragraph = paragraphs[paragraph_index] + run = paragraph.runs[0] + if 'strike' not in run.font._element.attrib: + return False + + return True -def check_file_exists(directory, filename): - file_path = os.path.join(directory, filename) - return 1 if os.path.isfile(file_path) else 0 def has_audio_on_page(slide): for shape in slide.shapes: @@ -77,6 +132,7 @@ def has_audio_on_page(slide): return True return False + def check_for_audio(prs): prs = Presentation(prs) for i, slide in enumerate(prs.slides): @@ -84,26 +140,29 @@ def check_for_audio(prs): return 1 return 0 + def check_formula_shape(prs): prs = Presentation(prs) slide = prs.slides[13] - + for shape in slide.shapes: if shape.has_text_frame and shape.shape_type == 1: return 1 return 0 + def check_slide_orientation_Portrait(pptx_path): presentation = Presentation(pptx_path) - + slide_height = presentation.slide_height slide_width = presentation.slide_width - + if slide_width < slide_height: return 1 return 0 + def contains_mp4_video(pptx_path): prs = Presentation(pptx_path) for slide in prs.slides: @@ -113,6 +172,7 @@ def contains_mp4_video(pptx_path): return 1 return 0 + if __name__ == "__main__": path1 = "../../任务数据/LibreOffice Impress/Change_Color_Slide_Number_gold_textbox.pptx" presentation = Presentation(path1) diff --git a/evaluation_examples/examples/libreoffice_impress/455d3c66-7dc6-4537-a39a-36d3e9119df7.json b/evaluation_examples/examples/libreoffice_impress/455d3c66-7dc6-4537-a39a-36d3e9119df7.json index 0a5ebb9..db194b0 100644 --- a/evaluation_examples/examples/libreoffice_impress/455d3c66-7dc6-4537-a39a-36d3e9119df7.json +++ b/evaluation_examples/examples/libreoffice_impress/455d3c66-7dc6-4537-a39a-36d3e9119df7.json @@ -27,8 +27,16 @@ "libreoffice_impress" ], "evaluator": { - "func": "check_file_exists", - "file_name": "res.png", - "directory": "/home/user/Desktop/" + "func": "compare_images", + "expected": { + "type": "cloud_file", + "path": "https://drive.usercontent.google.com/download?id=1XTDaQ2NlovrusKkuY6udi_BQfLwSP9th&export=download&authuser=0&confirm=t&uuid=d3c7883e-3cea-4bf3-8f83-d878622ee76d&at=APZUnTXQEnT0Gi4rB0oegvVGheyn:1705859805154", + "dest": "res_gold.png" + }, + "result": { + "type": "vm_file", + "path": "/home/user/Desktop/res.png", + "dest": "res.png" + } } } \ No newline at end of file diff --git a/evaluation_examples/examples/libreoffice_impress/550ce7e7-747b-495f-b122-acdc4d0b8e54.json b/evaluation_examples/examples/libreoffice_impress/550ce7e7-747b-495f-b122-acdc4d0b8e54.json index 318b981..6c0e229 100644 --- a/evaluation_examples/examples/libreoffice_impress/550ce7e7-747b-495f-b122-acdc4d0b8e54.json +++ b/evaluation_examples/examples/libreoffice_impress/550ce7e7-747b-495f-b122-acdc4d0b8e54.json @@ -27,7 +27,15 @@ "libreoffice_impress" ], "evaluator": { - "func": "check_for_two_lines", + "func": "check_strikethrough", + "expected": { + "type": "rule", + "rules": { + "slide_index_s": [4], + "shape_index_s": [1], + "paragraph_index_s": [1, 2] + } + }, "result": { "type": "vm_file", "path": "Desktop/New_Club_Spring_2018_Training.pptx", diff --git a/evaluation_examples/examples/libreoffice_impress/5d901039-a89c-4bfb-967b-bf66f4df075e.json b/evaluation_examples/examples/libreoffice_impress/5d901039-a89c-4bfb-967b-bf66f4df075e.json index 6c1f0f0..773ef8c 100644 --- a/evaluation_examples/examples/libreoffice_impress/5d901039-a89c-4bfb-967b-bf66f4df075e.json +++ b/evaluation_examples/examples/libreoffice_impress/5d901039-a89c-4bfb-967b-bf66f4df075e.json @@ -9,7 +9,7 @@ "parameters": { "files": [ { - "url": "https://drive.usercontent.google.com/download?id=16K6TpGIRZpqOJUu-mtJQ_78kIwLcn-4D&export=download&authuser=0&confirm=t&uuid=945b6f33-53d2-4e87-ada9-efa8b938a499&at=APZUnTVw4fKyJPW0vAAJURruAJIP:1705250184439", + "url": "https://drive.usercontent.google.com/download?id=16K6TpGIRZpqOJUu-mtJQ_78kIwLcn-4D&export=download&authuser=0&confirm=t&uuid=41509e5c-eb95-453a-baad-4e12a839a120&at=APZUnTVygE_LL27vx1l6OEg_FRj0:1705849959413", "path": "Desktop/CPD_Background_Investigation_Process.pptx" } ] @@ -27,11 +27,11 @@ "libreoffice_impress" ], "evaluator": { - "func": "compare_pptx_files", + "func": "check_image_stretch_and_center", "expected": { "type": "cloud_file", - "path": "https://drive.usercontent.google.com/download?id=1rsvFPyHYiIPh1c8Nj8say0NJCG2VIDr7&export=download&authuser=0&confirm=t&uuid=aac08a92-6595-47d8-84dc-8f1ab1df987f&at=APZUnTXIWCn5B0CpLttvG2bsr_a7:1705250423565", - "dest": "CPD_Background_Investigation_Process_Gold.docx" + "path": "https://drive.usercontent.google.com/download?id=16K6TpGIRZpqOJUu-mtJQ_78kIwLcn-4D&export=download&authuser=0&confirm=t&uuid=41509e5c-eb95-453a-baad-4e12a839a120&at=APZUnTVygE_LL27vx1l6OEg_FRj0:1705849959413", + "dest": "CPD_Background_Investigation_Process_Original.pptx" }, "result": { "type": "vm_file", diff --git a/evaluation_examples/examples/libreoffice_impress/ac9bb6cb-1888-43ab-81e4-a98a547918cd.json b/evaluation_examples/examples/libreoffice_impress/ac9bb6cb-1888-43ab-81e4-a98a547918cd.json index 7a8cb20..8b5dc98 100644 --- a/evaluation_examples/examples/libreoffice_impress/ac9bb6cb-1888-43ab-81e4-a98a547918cd.json +++ b/evaluation_examples/examples/libreoffice_impress/ac9bb6cb-1888-43ab-81e4-a98a547918cd.json @@ -6,7 +6,7 @@ "config": [], "trajectory": "trajectories/", "related_apps": [ - "" + "libreoffice_impress" ], "evaluator": "evaluation_dir" } diff --git a/evaluation_examples/examples/libreoffice_impress/af23762e-2bfd-4a1d-aada-20fa8de9ce07.json b/evaluation_examples/examples/libreoffice_impress/af23762e-2bfd-4a1d-aada-20fa8de9ce07.json index af3d921..a5213fe 100644 --- a/evaluation_examples/examples/libreoffice_impress/af23762e-2bfd-4a1d-aada-20fa8de9ce07.json +++ b/evaluation_examples/examples/libreoffice_impress/af23762e-2bfd-4a1d-aada-20fa8de9ce07.json @@ -1,7 +1,7 @@ { "id": "af23762e-2bfd-4a1d-aada-20fa8de9ce07", "snapshot": "libreoffice_impress", - "instruction": "I am making PPT on LibreOffice Impress for presentation tomorrow. I need to summarize contents on one slide. Could you make a summary slide for me?", + "instruction": "I am making PPT on LibreOffice Impress for presentation tomorrow. I need to summarize contents on one slide use Impress \"Summary Slide\" feature. Could you make that for me?", "source": "https://www.libreofficehelp.com/export-libreoffice-impress-slides-images/#:~:text=Exporting%20a%20single%20slide%20as.jpg%2C.png%2C%20etc%20image%20is,on%20the%20checkbox%20Selection.%20Provide%20jpg%20quality%20options.", "config": [ { diff --git a/evaluation_examples/examples/vlc/59f21cfb-0120-4326-b255-a5b827b38967.json b/evaluation_examples/examples/vlc/59f21cfb-0120-4326-b255-a5b827b38967.json index 32d7570..14ce3cd 100644 --- a/evaluation_examples/examples/vlc/59f21cfb-0120-4326-b255-a5b827b38967.json +++ b/evaluation_examples/examples/vlc/59f21cfb-0120-4326-b255-a5b827b38967.json @@ -1,7 +1,7 @@ { "id": "59f21cfb-0120-4326-b255-a5b827b38967", "snapshot": "base_setup", - "instruction": "Could you play the music video that's saved on my desktop for me?", + "instruction": "Could you play the music video that's saved on my desktop for me via vlc?", "source": "https://docs.videolan.me/vlc-user/desktop/3.0/en/basic/media.html#playing-a-file", "config": [ {