Commit 4a82a1ab authored by Vũ Hoàng Anh's avatar Vũ Hoàng Anh

fix: detect ext from content_type when filename has no extension + detailed strategy logging

parent 333179a7
......@@ -74,6 +74,9 @@ MIME_MAP = {
".jpeg": "image/jpeg",
}
# Reverse lookup: content_type → ext (dùng khi filename không có extension)
MIME_TO_EXT = {v: k for k, v in MIME_MAP.items()}
def _count_dieu(text: str) -> int:
"""Đếm số lần xuất hiện pattern 'Điều X' / 'ĐIỀU X'."""
......@@ -371,43 +374,65 @@ def _convert_document(file_bytes: bytes, filename: str, content_type: str) -> di
"""
Chạy tất cả strategies phù hợp, chọn output nhiều "Điều" nhất.
DOCX → chạy cả 3 strategy (A + B + C)
DOCX → chạy 4 strategy (A + A2 + B + C)
DOC → chạy 2 strategy (B + C), vì python-docx không đọc .doc
"""
ext = os.path.splitext(filename)[1].lower()
# ── Fix: detect ext từ content_type nếu filename không có extension ──
if not ext and content_type:
ext = MIME_TO_EXT.get(content_type, "")
if ext:
logger.info(f" [EXT] Filename '{filename}' không có extension, detect từ content_type → ext={ext}")
if not content_type:
content_type = MIME_MAP.get(ext, "application/octet-stream")
logger.info(f"Converting: {filename} ({len(file_bytes)} bytes, ext={ext})")
logger.info(
f"Converting: {filename} ({len(file_bytes)} bytes, "
f"ext={ext}, content_type={content_type})"
)
is_docx = ext == ".docx"
is_doc = ext == ".doc"
candidates = []
# ── Strategy A: docx_converter (chỉ .docx) ──
if ext == ".docx":
if is_docx:
logger.info(" [STRATEGY A: docx_native] Running — parse XML numbering.xml...")
result_a = _strategy_docx_native(file_bytes, filename)
candidates.append(result_a)
# Nếu Strategy A đã có "Điều" → skip tất cả
if _count_dieu(result_a["md"]) > 0 and _meaningful_chars(result_a["md"]) > 200:
logger.info(f" Strategy A đã có Điều, skip các strategy khác")
logger.info(f" ✅ Strategy A có {_count_dieu(result_a['md'])} Điều → DONE, skip A2/B/C")
best = result_a
return _build_response(filename, best, candidates)
else:
logger.info(f" ❌ Strategy A: {_count_dieu(result_a['md'])} Điều → thử A2...")
# ── Strategy A2: mammoth DOCX → HTML → markdown (chỉ .docx) ──
# ── Strategy A2: mammoth DOCX → HTML → markdown ──
logger.info(" [STRATEGY A2: docx_html] Running — mammoth DOCX→HTML→MD...")
result_a2 = _strategy_docx_html(file_bytes, filename)
candidates.append(result_a2)
# Nếu A2 đã có "Điều" → skip Drive calls
if _count_dieu(result_a2["md"]) > 0 and _meaningful_chars(result_a2["md"]) > 200:
logger.info(f" Strategy A2 (HTML) đã có Điều, skip Drive calls")
logger.info(f" ✅ Strategy A2 có {_count_dieu(result_a2['md'])} Điều → DONE, skip B/C")
best = _pick_best(*candidates)
return _build_response(filename, best, candidates)
else:
logger.info(f" ❌ Strategy A2: {_count_dieu(result_a2['md'])} Điều → thử B/C (Drive)...")
else:
logger.info(f" [SKIP A, A2] ext={ext} không phải .docx → skip offline strategies")
# ── Strategy B: Drive → DOCX → docx_converter ──
logger.info(" [STRATEGY B: drive_docx] Running — upload Drive → export DOCX → parse...")
result_b = _strategy_drive_docx(file_bytes, filename, content_type)
candidates.append(result_b)
# ── Strategy C: Drive → text → regex ──
logger.info(" [STRATEGY C: drive_text] Running — upload Drive → export text → regex...")
result_c = _strategy_drive_text(file_bytes, filename, content_type)
candidates.append(result_c)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment