v0.0.30: .doc поддержка — accept + liberta API вместо LibreOffice
Deploy drhider / validate (push) Waiting to run
Deploy drhider / validate (push) Waiting to run
This commit is contained in:
+24
-30
@@ -149,14 +149,14 @@ def pdf_to_markdown(content: bytes) -> str:
|
|||||||
|
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════
|
||||||
# DOC → Markdown (через LibreOffice)
|
# DOC → Markdown (через сервис liberta)
|
||||||
# ═══════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
def doc_to_markdown(content: bytes) -> str:
|
def doc_to_markdown(content: bytes) -> str:
|
||||||
"""Конвертировать бинарный .doc → .docx (LibreOffice) → Markdown.
|
"""Конвертировать бинарный .doc → .docx (сервис liberta) → Markdown.
|
||||||
|
|
||||||
Использует soffice --headless --convert-to docx, затем прогоняет
|
Отправляет .doc на HTTP-сервис конвертации, получает .docx,
|
||||||
через штатный docx_to_markdown() с полным форматированием и таблицами.
|
затем прогоняет через штатный docx_to_markdown().
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
content: Бинарное содержимое .doc файла
|
content: Бинарное содержимое .doc файла
|
||||||
@@ -164,33 +164,27 @@ def doc_to_markdown(content: bytes) -> str:
|
|||||||
Returns:
|
Returns:
|
||||||
Строка в формате Markdown (или сообщение об ошибке)
|
Строка в формате Markdown (или сообщение об ошибке)
|
||||||
"""
|
"""
|
||||||
tmpdir = tempfile.mkdtemp()
|
import httpx
|
||||||
doc_path = os.path.join(tmpdir, "input.doc")
|
url = os.environ.get(
|
||||||
|
"CONVERT_SERVICE_URL",
|
||||||
|
"https://liberta.containerk8s.dev.nubes.ru/convert"
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
with open(doc_path, 'wb') as f:
|
with httpx.Client(timeout=120) as client:
|
||||||
f.write(content)
|
resp = client.post(
|
||||||
|
url,
|
||||||
result = subprocess.run(
|
files={"file": ("input.doc", content, "application/msword")}
|
||||||
["soffice", "--headless", "--convert-to", "docx",
|
)
|
||||||
"--outdir", tmpdir, doc_path],
|
if resp.status_code == 200:
|
||||||
timeout=60, capture_output=True
|
return docx_to_markdown(resp.content)
|
||||||
)
|
err = resp.json().get("error", f"HTTP {resp.status_code}")
|
||||||
|
log.warning("liberta conversion failed: %s", err)
|
||||||
docx_path = os.path.join(tmpdir, "input.docx")
|
return f"[DOC — conversion failed: {err}]"
|
||||||
if os.path.exists(docx_path):
|
except httpx.TimeoutException:
|
||||||
with open(docx_path, 'rb') as f:
|
return "[DOC — conversion timed out (>120s)]"
|
||||||
return docx_to_markdown(f.read())
|
except Exception as e:
|
||||||
|
log.warning("liberta error: %s", e)
|
||||||
stderr = result.stderr.decode('utf-8', errors='replace').strip()
|
return f"[DOC — conversion error: {e}]"
|
||||||
log.warning("LibreOffice conversion failed: %s", stderr)
|
|
||||||
return f"[DOC — LibreOffice conversion failed: {stderr}]"
|
|
||||||
|
|
||||||
except FileNotFoundError:
|
|
||||||
return "[DOC — LibreOffice not installed. Install: apt install libreoffice-writer]"
|
|
||||||
except subprocess.TimeoutExpired:
|
|
||||||
return "[DOC — conversion timed out (>60s)]"
|
|
||||||
finally:
|
|
||||||
shutil.rmtree(tmpdir, ignore_errors=True)
|
|
||||||
|
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ if _sys_path_root not in sys.path:
|
|||||||
sys.path.insert(0, _sys_path_root)
|
sys.path.insert(0, _sys_path_root)
|
||||||
|
|
||||||
# Версия приложения (меняется при изменениях)
|
# Версия приложения (меняется при изменениях)
|
||||||
VERSION = "0.0.29"
|
VERSION = "0.0.30"
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
CSV с таблицей замен скачивается отдельно.
|
CSV с таблицей замен скачивается отдельно.
|
||||||
</p>
|
</p>
|
||||||
<div class="file-input-wrap">
|
<div class="file-input-wrap">
|
||||||
<input type="file" id="fileInput" multiple accept=".docx,.pdf,.txt,.zip">
|
<input type="file" id="fileInput" multiple accept=".doc,.docx,.pdf,.txt,.zip">
|
||||||
</div>
|
</div>
|
||||||
<div class="table-wrap">
|
<div class="table-wrap">
|
||||||
<table>
|
<table>
|
||||||
|
|||||||
Reference in New Issue
Block a user