Impress eval fix (#226)

* fix compare_pptx

* Fix impress-4ed5abd0-8b5d-47bd-839f-cacfa15ca37a eval script:Fix temporarily by ignoring the contaminated  To fix completely, compare source file needs to be updated

* fix impress domain

* fix a53 by changing gold

* fix impress a53

* fix impress b8d origin file

* add table font color check

* fix left pane check

---------

Co-authored-by: chenjix <3107760494@qq.com>
Co-authored-by: moonshot <moonshot@moonshotznshenMacBook-Pro.local>
Co-authored-by: Shen Zhennan <shenzhennan@moonshot.cn>
This commit is contained in:
Shenzhennan
2025-07-04 13:32:02 +08:00
committed by GitHub
parent 587f929567
commit 1b40a458de
16 changed files with 103 additions and 39 deletions

View File

@@ -5,6 +5,7 @@ from math import sqrt
from pptx import Presentation
from pptx.util import Inches
from pptx.enum.shapes import MSO_SHAPE_TYPE
logger = logging.getLogger("desktopenv.metric.slides")
@@ -139,6 +140,17 @@ def compare_pptx_files(file1_path, file2_path, **options):
prs1 = Presentation(file1_path)
prs2 = Presentation(file2_path)
approximately_tolerance = options.get("approximately_tolerance", 0.005)
def is_approximately_equal(val1, val2, tolerance=approximately_tolerance):
"""Compare two values with a tolerance of 0.1% (0.005)"""
if val1 == val2:
return True
if val1 == 0 and val2 == 0:
return True
if val1 == 0 or val2 == 0:
return False
return abs(val1 - val2) / max(abs(val1), abs(val2)) <= tolerance
examine_number_of_slides = options.get("examine_number_of_slides", True)
examine_shape = options.get("examine_shape", True)
examine_text = options.get("examine_text", True)
@@ -212,14 +224,20 @@ def compare_pptx_files(file1_path, file2_path, **options):
if hasattr(shape1, "text") and hasattr(shape2, "text") and shape1.text == shape2.text:
if shape1.text == "Product Comparison" and (shape1.top <= shape2.top or shape1.top < 3600000):
return 0
elif shape1.left != shape2.left or shape1.top != shape2.top or shape1.width != shape2.width or shape1.height != shape2.height:
elif (not is_approximately_equal(shape1.left, shape2.left) or
not is_approximately_equal(shape1.top, shape2.top) or
not is_approximately_equal(shape1.width, shape2.width) or
not is_approximately_equal(shape1.height, shape2.height)):
return 0
if examine_table_bottom_position:
if slide_idx == 3 and shape1.shape_type == 19 and shape2.shape_type == 19:
if shape1.top <= shape2.top or shape1.top < 3600000:
return 0
elif shape1.left != shape2.left or shape1.top != shape2.top or shape1.width != shape2.width or shape1.height != shape2.height:
elif (not is_approximately_equal(shape1.left, shape2.left) or
not is_approximately_equal(shape1.top, shape2.top) or
not is_approximately_equal(shape1.width, shape2.width) or
not is_approximately_equal(shape1.height, shape2.height)):
return 0
if examine_right_position:
@@ -231,34 +249,62 @@ def compare_pptx_files(file1_path, file2_path, **options):
if slide_idx == 2 and shape1.shape_type == 13 and shape2.shape_type == 13:
if shape1.top >= shape2.top or shape1.top > 1980000:
return 0
elif shape1.left != shape2.left or shape1.top != shape2.top or shape1.width != shape2.width or shape1.height != shape2.height:
elif (not is_approximately_equal(shape1.left, shape2.left) or
not is_approximately_equal(shape1.top, shape2.top) or
not is_approximately_equal(shape1.width, shape2.width) or
not is_approximately_equal(shape1.height, shape2.height)):
return 0
if examine_shape_for_shift_size:
if shape1.left != shape2.left or shape1.top != shape2.top or shape1.width != shape2.width or shape1.height != shape2.height:
if (not is_approximately_equal(shape1.left, shape2.left) or
not is_approximately_equal(shape1.top, shape2.top) or
not is_approximately_equal(shape1.width, shape2.width) or
not is_approximately_equal(shape1.height, shape2.height)):
if not (hasattr(shape1, "text") and hasattr(shape2,
"text") and shape1.text == shape2.text and shape1.text == "Elaborate on what you want to discuss."):
return 0
if (
shape1.left != shape2.left or shape1.top != shape2.top or shape1.width != shape2.width or shape1.height != shape2.height) and examine_shape:
not is_approximately_equal(shape1.left, shape2.left) or
not is_approximately_equal(shape1.top, shape2.top) or
not is_approximately_equal(shape1.width, shape2.width) or
not is_approximately_equal(shape1.height, shape2.height)) and examine_shape:
return 0
if examine_image_size:
if shape1.shape_type == 13 and shape2.shape_type == 13:
if shape1.width != shape2.width or shape1.height != shape2.height:
if not is_approximately_equal(shape1.width, shape2.width) or not is_approximately_equal(shape1.height, shape2.height):
return 0
elif shape1.left != shape2.left or shape1.top != shape2.top or shape1.width != shape2.width or shape1.height != shape2.height:
elif (not is_approximately_equal(shape1.left, shape2.left) or
not is_approximately_equal(shape1.top, shape2.top) or
not is_approximately_equal(shape1.width, shape2.width) or
not is_approximately_equal(shape1.height, shape2.height)):
return 0
if examine_modify_height:
if not hasattr(shape1, "text") and not hasattr(shape2,
"text") or shape1.shape_type == 5 and shape2.shape_type == 5:
if shape1.height != shape2.height:
if not is_approximately_equal(shape1.height, shape2.height):
return 0
elif shape1.left != shape2.left or shape1.top != shape2.top or shape1.width != shape2.width or shape1.height != shape2.height:
elif (not is_approximately_equal(shape1.left, shape2.left) or
not is_approximately_equal(shape1.top, shape2.top) or
not is_approximately_equal(shape1.width, shape2.width) or
not is_approximately_equal(shape1.height, shape2.height)):
return 0
if shape1.shape_type == MSO_SHAPE_TYPE.TABLE:
table1 = shape1.table
table2 = shape2.table
for row_idx in range(len(table1.rows)):
for col_idx in range(len(table1.columns)):
cell1 = table1.cell(row_idx, col_idx)
cell2 = table2.cell(row_idx, col_idx)
for para1, para2 in zip(cell1.text_frame.paragraphs, cell2.text_frame.paragraphs):
for run1, run2 in zip(para1.runs, para2.runs):
if run1.font.color.rgb != run2.font.color.rgb:
return 0
if hasattr(shape1, "text") and hasattr(shape2, "text"):
if shape1.text.strip() != shape2.text.strip() and examine_text:
return 0
@@ -288,15 +334,19 @@ def compare_pptx_files(file1_path, file2_path, **options):
return 0
if run1.font.italic != run2.font.italic and examine_font_italic:
return 0
if run1.font.italic is not None and run2.font.italic is not None:
return 0
if hasattr(run1.font.color, "rgb") and hasattr(run2.font.color, "rgb"):
if run1.font.color.rgb != run2.font.color.rgb and examine_color_rgb:
return 0
if run1.font.underline != run2.font.underline and examine_font_underline:
return 0
if run1.font.underline is not None and run2.font.underline is not None:
return 0
if (run1.font.underline is None and run2.font.underline is True) or (run1.font.underline is True and run2.font.underline is None):
return 0
if run1.font._element.attrib.get('strike', 'noStrike') != run2.font._element.attrib.get(
'strike', 'noStrike') and examine_strike_through:
return 0
@@ -325,14 +375,20 @@ def compare_pptx_files(file1_path, file2_path, **options):
color = "No Color"
text = "".join(t.text for t in paragraph.findall('.//a:t', namespaces))
bullets.append((lvl, char, text, color))
# Only add non-empty paragraphs to bullets list
if text.strip():
bullets.append((lvl, char, text, color))
return bullets
if examine_bullets and _extract_bullets(run1.part.blob.decode('utf-8')) != _extract_bullets(
run2.part.blob.decode('utf-8')):
return 0
if examine_bullets:
bullets1 = _extract_bullets(run1.part.blob.decode('utf-8'))
bullets2 = _extract_bullets(run2.part.blob.decode('utf-8'))
# Compare only non-empty bullets
if bullets1 != bullets2:
return 0
# fixme: Actually there are more properties to be compared, we can add them later via parsing the xml data
@@ -446,17 +502,13 @@ def check_left_panel(accessibility_tree):
root = ET.fromstring(accessibility_tree)
for root_pane in root.iter('root-pane'):
for panel in root_pane.iter('panel'):
for split_pane in panel.iter('split-pane'):
# Get the left panel
if split_pane.attrib.get("{{{}}}parentcoord".format(namespaces['cp'])) == "(0, 0)":
# Get the visible attribute
visible = split_pane.attrib.get("{{{}}}visible".format(namespaces['st']))
if visible:
# decide if it is left panel
return 1.
# 遍历所有 document-frame 节点
for doc_frame in root.iter('document-frame'):
if doc_frame.attrib.get("name") == "Slides View":
# 说明 Slides View 存在,即左侧面板已打开
return 1.
# 没找到 Slides View认为左侧面板未打开
return 0.