Revert "feat: поддержка .doc через LibreOffice headless"
Deploy drhider / validate (push) Waiting to run

This reverts commit 00d54dbfb6.
This commit is contained in:
2026-07-14 08:56:54 +04:00
parent e193c5462b
commit 23ffc1c55d
4 changed files with 5 additions and 56 deletions
-3
View File
@@ -1,8 +1,5 @@
FROM python:3.12-slim FROM python:3.12-slim
WORKDIR /app WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
libreoffice-writer \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt . COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
COPY site /app/site COPY site /app/site
+1 -1
View File
@@ -45,7 +45,7 @@ site/app.py ──→ Flask (create_app)
| **`.pdf`** | → Markdown | Текст + таблицы (`pdfplumber`), без форматирования | | **`.pdf`** | → Markdown | Текст + таблицы (`pdfplumber`), без форматирования |
| **`.txt`** и прочие текстовые | → как есть | Декодируется UTF-8, ошибки заменяются `` | | **`.txt`** и прочие текстовые | → как есть | Декодируется UTF-8, ошибки заменяются `` |
| **`.zip`** | → распаковка | Файлы внутри обрабатываются рекурсивно. Защита от ZIP-бомб: ≤500 файлов, ratio ≤100:1, ≤500 MB | | **`.zip`** | → распаковка | Файлы внутри обрабатываются рекурсивно. Защита от ZIP-бомб: ≤500 файлов, ratio ≤100:1, ≤500 MB |
| **`.doc`** (бинарный) | → Docx → Markdown | LibreOffice headless: .doc → .docx → штатный `docx_to_markdown()` (таблицы, форматирование). Требует `libreoffice-writer` в контейнере | | **`.doc`** (бинарный) | ❌ не поддерживается | Возвращает заглушку `[DOC binary — not supported. Convert to .docx first.]` |
Ограничение на размер загрузки: **200 MB** (`MAX_CONTENT_LENGTH`). Ограничение на размер загрузки: **200 MB** (`MAX_CONTENT_LENGTH`).
+3 -51
View File
@@ -4,7 +4,7 @@
Поддерживает: Поддерживает:
- .docx → MD (python-docx: стили, жирный/курсив, таблицы) - .docx → MD (python-docx: стили, жирный/курсив, таблицы)
- .pdf → MD (pdfplumber: текст + таблицы, без форматирования) - .pdf → MD (pdfplumber: текст + таблицы, без форматирования)
- .doc → MD (LibreOffice headless: .doc → .docx → штатный docx_to_markdown) - .doc (бинарный — не парсится, возвращает заглушку)
- .txt и прочие → как есть - .txt и прочие → как есть
Также содержит: Также содержит:
@@ -14,9 +14,6 @@
import io import io
import os import os
import zipfile import zipfile
import tempfile
import shutil
import subprocess
import logging import logging
from typing import List, Tuple from typing import List, Tuple
@@ -148,51 +145,6 @@ def pdf_to_markdown(content: bytes) -> str:
return "\n".join(lines) return "\n".join(lines)
# ═══════════════════════════════════════════════════════════════════════════
# DOC → Markdown (через LibreOffice)
# ═══════════════════════════════════════════════════════════════════════════
def doc_to_markdown(content: bytes) -> str:
"""Конвертировать бинарный .doc → .docx (LibreOffice) → Markdown.
Использует soffice --headless --convert-to docx, затем прогоняет
через штатный docx_to_markdown() с полным форматированием и таблицами.
Args:
content: Бинарное содержимое .doc файла
Returns:
Строка в формате Markdown (или сообщение об ошибке)
"""
tmpdir = tempfile.mkdtemp()
doc_path = os.path.join(tmpdir, "input.doc")
try:
with open(doc_path, 'wb') as f:
f.write(content)
result = subprocess.run(
["soffice", "--headless", "--convert-to", "docx",
"--outdir", tmpdir, doc_path],
timeout=60, capture_output=True
)
docx_path = os.path.join(tmpdir, "input.docx")
if os.path.exists(docx_path):
with open(docx_path, 'rb') as f:
return docx_to_markdown(f.read())
stderr = result.stderr.decode('utf-8', errors='replace').strip()
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)
# ═══════════════════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════════════════
# Единая точка входа # Единая точка входа
# ═══════════════════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════════════════
@@ -224,9 +176,9 @@ def extract_text(fname: str, content: bytes, ctype: str = "") -> str:
except ImportError: except ImportError:
return content.decode('utf-8', errors='replace') return content.decode('utf-8', errors='replace')
# ── .doc: бинарный → LibreOffice → DOCX → Markdown ── # ── .doc: бинарный — пока не поддерживается ──
elif ext == '.doc': elif ext == '.doc':
return doc_to_markdown(content) return "[DOC binary — not supported. Convert to .docx first.]"
# ── .txt и прочие ── # ── .txt и прочие ──
else: else:
+1 -1
View File
@@ -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.17" VERSION = "0.0.16"
def create_app(): def create_app():