fix(parser): 修复 Docling 图片异常占位回填
保留上传失败的图片占位说明,并补充混合图片类型回填顺序的回归测试,避免占位符错位或异常路径掩盖原始错误。 Taskr: 2026-05-12-fix-docling-image-replacement-regression
This commit is contained in:
parent
56166abff6
commit
bdf983f1e0
@ -131,6 +131,7 @@ def _convert_with_docling(file_path: Path, params: dict | None = None) -> str:
|
|||||||
for pic in doc.pictures:
|
for pic in doc.pictures:
|
||||||
uri = str(pic.image.uri) if hasattr(pic, "image") and hasattr(pic.image, "uri") else ""
|
uri = str(pic.image.uri) if hasattr(pic, "image") and hasattr(pic.image, "uri") else ""
|
||||||
if uri.startswith("data:"):
|
if uri.startswith("data:"):
|
||||||
|
filename = "image"
|
||||||
try:
|
try:
|
||||||
image_data, mime_type = _parse_data_uri(uri)
|
image_data, mime_type = _parse_data_uri(uri)
|
||||||
filename = f"image_{int(time.time() * 1000000)}.{mime_type.split('/')[-1]}"
|
filename = f"image_{int(time.time() * 1000000)}.{mime_type.split('/')[-1]}"
|
||||||
@ -138,7 +139,7 @@ def _convert_with_docling(file_path: Path, params: dict | None = None) -> str:
|
|||||||
replacements.append(f"")
|
replacements.append(f"")
|
||||||
except Exception as e: # noqa: BLE001
|
except Exception as e: # noqa: BLE001
|
||||||
logger.error(f"上传图片失败 {filename}: {e}")
|
logger.error(f"上传图片失败 {filename}: {e}")
|
||||||
replacements.append("")
|
replacements.append(f"[图片: {filename}]")
|
||||||
else:
|
else:
|
||||||
replacements.append("")
|
replacements.append("")
|
||||||
|
|
||||||
|
|||||||
@ -76,9 +76,10 @@ def test_convert_with_docling_reinserts_image_links_in_document_order(
|
|||||||
fake_doc = SimpleNamespace(
|
fake_doc = SimpleNamespace(
|
||||||
pictures=[
|
pictures=[
|
||||||
SimpleNamespace(image=SimpleNamespace(uri=f"data:image/png;base64,{first_image}")),
|
SimpleNamespace(image=SimpleNamespace(uri=f"data:image/png;base64,{first_image}")),
|
||||||
|
SimpleNamespace(image=SimpleNamespace(uri="https://example.test/remote.png")),
|
||||||
SimpleNamespace(image=SimpleNamespace(uri=f"data:image/png;base64,{second_image}")),
|
SimpleNamespace(image=SimpleNamespace(uri=f"data:image/png;base64,{second_image}")),
|
||||||
],
|
],
|
||||||
export_to_markdown=lambda: "before\n<!-- image -->\nbetween\n<!-- image -->\nafter",
|
export_to_markdown=lambda: "before\n<!-- image -->\nremote\n<!-- image -->\nbetween\n<!-- image -->\nafter",
|
||||||
)
|
)
|
||||||
fake_result = SimpleNamespace(status=SimpleNamespace(name="SUCCESS"), document=fake_doc)
|
fake_result = SimpleNamespace(status=SimpleNamespace(name="SUCCESS"), document=fake_doc)
|
||||||
uploaded_images: list[bytes] = []
|
uploaded_images: list[bytes] = []
|
||||||
@ -103,12 +104,44 @@ def test_convert_with_docling_reinserts_image_links_in_document_order(
|
|||||||
assert markdown == (
|
assert markdown == (
|
||||||
"before\n"
|
"before\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"remote\n"
|
||||||
|
"\n"
|
||||||
"between\n"
|
"between\n"
|
||||||
"\n"
|
"\n"
|
||||||
"after"
|
"after"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_convert_with_docling_keeps_image_placeholder_when_upload_fails(
|
||||||
|
tmp_path: Path,
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
):
|
||||||
|
file_path = tmp_path / "parser_test.docx"
|
||||||
|
file_path.write_bytes(b"fake docx")
|
||||||
|
image = base64.b64encode(b"image data").decode()
|
||||||
|
fake_doc = SimpleNamespace(
|
||||||
|
pictures=[SimpleNamespace(image=SimpleNamespace(uri=f"data:image/png;base64,{image}"))],
|
||||||
|
export_to_markdown=lambda: "before\n<!-- image -->\nafter",
|
||||||
|
)
|
||||||
|
fake_result = SimpleNamespace(status=SimpleNamespace(name="SUCCESS"), document=fake_doc)
|
||||||
|
|
||||||
|
class FakeConverter:
|
||||||
|
def convert(self, path: Path):
|
||||||
|
assert path == file_path
|
||||||
|
return fake_result
|
||||||
|
|
||||||
|
def _raise_upload_error(*args, **kwargs):
|
||||||
|
raise RuntimeError("upload failed")
|
||||||
|
|
||||||
|
monkeypatch.setattr(parser_unified, "_get_docling_converter", lambda: FakeConverter())
|
||||||
|
monkeypatch.setattr(parser_unified, "_upload_image_to_minio", _raise_upload_error)
|
||||||
|
monkeypatch.setattr(parser_unified.time, "time", lambda: 1.0)
|
||||||
|
|
||||||
|
markdown = parser_unified._convert_with_docling(file_path)
|
||||||
|
|
||||||
|
assert markdown == "before\n[图片: image_1000000.png]\nafter"
|
||||||
|
|
||||||
|
|
||||||
def test_parser_parse_png_file_returns_markdown_text_with_mocked_ocr(
|
def test_parser_parse_png_file_returns_markdown_text_with_mocked_ocr(
|
||||||
tmp_path: Path,
|
tmp_path: Path,
|
||||||
monkeypatch: pytest.MonkeyPatch,
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user