Loading Impress v1 batch
This commit is contained in:
@@ -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 .general import check_csv, check_accessibility_tree, check_list, run_sqlite3, check_json
|
||||||
from .thunderbird import check_thunderbird_prefs, check_thunderbird_filter
|
from .thunderbird import check_thunderbird_prefs, check_thunderbird_filter
|
||||||
from .vscode import compare_text_file, compare_config, compare_answer, is_extension_installed
|
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_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
|
from .impress import check_slide_orientation_Portrait, contains_mp4_video
|
||||||
@@ -1,11 +1,43 @@
|
|||||||
from pptx import Presentation
|
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):
|
def is_red_color(color):
|
||||||
#judge if the color is red
|
# judge if the color is red
|
||||||
print(color.rgb)
|
print(color.rgb)
|
||||||
return color and color.rgb == (255, 0, 0)
|
return color and color.rgb == (255, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
def get_master_placeholder_color(prs):
|
def get_master_placeholder_color(prs):
|
||||||
# get the color of the placeholder
|
# get the color of the placeholder
|
||||||
masters = prs.slide_masters
|
masters = prs.slide_masters
|
||||||
@@ -34,42 +66,65 @@ def check_slide_numbers_color(pptx_file_path):
|
|||||||
print(font_color)
|
print(font_color)
|
||||||
return 1 if font_color is not None and is_red_color(font_color) else 0
|
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)
|
prs1 = Presentation(file1_path)
|
||||||
prs2 = Presentation(file2_path)
|
prs2 = Presentation(file2_path)
|
||||||
|
|
||||||
# compare the number of slides
|
# compare the number of slides
|
||||||
if len(prs1.slides) != len(prs2.slides):
|
if len(prs1.slides) != len(prs2.slides):
|
||||||
return 0
|
return False
|
||||||
|
|
||||||
# compare the content of each slide
|
# compare the content of each slide
|
||||||
for slide1, slide2 in zip(prs1.slides, prs2.slides):
|
for slide1, slide2 in zip(prs1.slides, prs2.slides):
|
||||||
# check if the shapes are the same
|
# check if the shapes are the same
|
||||||
for shape1, shape2 in zip(slide1.shapes, slide2.shapes):
|
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 hasattr(shape1, "text") and hasattr(shape2, "text"):
|
||||||
if shape1.text != shape2.text:
|
if shape1.text != shape2.text:
|
||||||
return 0
|
return False
|
||||||
return 1
|
|
||||||
|
|
||||||
def has_two_lines_on_page(slide):
|
# check if the paragraphs are the same
|
||||||
line_count = 0
|
for para1, para2 in zip(shape1.text_frame.paragraphs, shape2.text_frame.paragraphs):
|
||||||
for shape in slide.shapes:
|
# check if the runs are the same
|
||||||
if shape.shape_type == 1: # 1 表示 Line 形状
|
for run1, run2 in zip(para1.runs, para2.runs):
|
||||||
line_count += 1
|
if run1.text != run2.text:
|
||||||
if line_count >= 2:
|
return False
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def check_for_two_lines(prs):
|
# check if the font properties are the same
|
||||||
prs = Presentation(prs)
|
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:
|
||||||
for i, slide in enumerate(prs.slides):
|
return False
|
||||||
if has_two_lines_on_page(slide):
|
|
||||||
return 1
|
return True
|
||||||
return 0
|
|
||||||
|
|
||||||
|
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):
|
def has_audio_on_page(slide):
|
||||||
for shape in slide.shapes:
|
for shape in slide.shapes:
|
||||||
@@ -77,6 +132,7 @@ def has_audio_on_page(slide):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def check_for_audio(prs):
|
def check_for_audio(prs):
|
||||||
prs = Presentation(prs)
|
prs = Presentation(prs)
|
||||||
for i, slide in enumerate(prs.slides):
|
for i, slide in enumerate(prs.slides):
|
||||||
@@ -84,6 +140,7 @@ def check_for_audio(prs):
|
|||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def check_formula_shape(prs):
|
def check_formula_shape(prs):
|
||||||
prs = Presentation(prs)
|
prs = Presentation(prs)
|
||||||
slide = prs.slides[13]
|
slide = prs.slides[13]
|
||||||
@@ -94,6 +151,7 @@ def check_formula_shape(prs):
|
|||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def check_slide_orientation_Portrait(pptx_path):
|
def check_slide_orientation_Portrait(pptx_path):
|
||||||
presentation = Presentation(pptx_path)
|
presentation = Presentation(pptx_path)
|
||||||
|
|
||||||
@@ -104,6 +162,7 @@ def check_slide_orientation_Portrait(pptx_path):
|
|||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def contains_mp4_video(pptx_path):
|
def contains_mp4_video(pptx_path):
|
||||||
prs = Presentation(pptx_path)
|
prs = Presentation(pptx_path)
|
||||||
for slide in prs.slides:
|
for slide in prs.slides:
|
||||||
@@ -113,6 +172,7 @@ def contains_mp4_video(pptx_path):
|
|||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
path1 = "../../任务数据/LibreOffice Impress/Change_Color_Slide_Number_gold_textbox.pptx"
|
path1 = "../../任务数据/LibreOffice Impress/Change_Color_Slide_Number_gold_textbox.pptx"
|
||||||
presentation = Presentation(path1)
|
presentation = Presentation(path1)
|
||||||
|
|||||||
@@ -27,8 +27,16 @@
|
|||||||
"libreoffice_impress"
|
"libreoffice_impress"
|
||||||
],
|
],
|
||||||
"evaluator": {
|
"evaluator": {
|
||||||
"func": "check_file_exists",
|
"func": "compare_images",
|
||||||
"file_name": "res.png",
|
"expected": {
|
||||||
"directory": "/home/user/Desktop/"
|
"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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,15 @@
|
|||||||
"libreoffice_impress"
|
"libreoffice_impress"
|
||||||
],
|
],
|
||||||
"evaluator": {
|
"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": {
|
"result": {
|
||||||
"type": "vm_file",
|
"type": "vm_file",
|
||||||
"path": "Desktop/New_Club_Spring_2018_Training.pptx",
|
"path": "Desktop/New_Club_Spring_2018_Training.pptx",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"parameters": {
|
"parameters": {
|
||||||
"files": [
|
"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"
|
"path": "Desktop/CPD_Background_Investigation_Process.pptx"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -27,11 +27,11 @@
|
|||||||
"libreoffice_impress"
|
"libreoffice_impress"
|
||||||
],
|
],
|
||||||
"evaluator": {
|
"evaluator": {
|
||||||
"func": "compare_pptx_files",
|
"func": "check_image_stretch_and_center",
|
||||||
"expected": {
|
"expected": {
|
||||||
"type": "cloud_file",
|
"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",
|
"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_Gold.docx"
|
"dest": "CPD_Background_Investigation_Process_Original.pptx"
|
||||||
},
|
},
|
||||||
"result": {
|
"result": {
|
||||||
"type": "vm_file",
|
"type": "vm_file",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"config": [],
|
"config": [],
|
||||||
"trajectory": "trajectories/",
|
"trajectory": "trajectories/",
|
||||||
"related_apps": [
|
"related_apps": [
|
||||||
""
|
"libreoffice_impress"
|
||||||
],
|
],
|
||||||
"evaluator": "evaluation_dir"
|
"evaluator": "evaluation_dir"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "af23762e-2bfd-4a1d-aada-20fa8de9ce07",
|
"id": "af23762e-2bfd-4a1d-aada-20fa8de9ce07",
|
||||||
"snapshot": "libreoffice_impress",
|
"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.",
|
"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": [
|
"config": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "59f21cfb-0120-4326-b255-a5b827b38967",
|
"id": "59f21cfb-0120-4326-b255-a5b827b38967",
|
||||||
"snapshot": "base_setup",
|
"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",
|
"source": "https://docs.videolan.me/vlc-user/desktop/3.0/en/basic/media.html#playing-a-file",
|
||||||
"config": [
|
"config": [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user