feat: HWP 파일 지원 — LibreOffice 변환
Browse files- Dockerfile: libreoffice-writer 설치 추가
- app.py: _ext_hwp()를 LibreOffice --headless 방식으로 구현
(pyhwp 대신 LibreOffice subprocess로 .hwp → txt 변환)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Dockerfile +5 -0
- app.py +16 -6
Dockerfile
CHANGED
|
@@ -2,6 +2,11 @@ FROM python:3.11-slim
|
|
| 2 |
|
| 3 |
WORKDIR /code
|
| 4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
COPY requirements.txt .
|
| 6 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 7 |
|
|
|
|
| 2 |
|
| 3 |
WORKDIR /code
|
| 4 |
|
| 5 |
+
# LibreOffice: .hwp 파일을 텍스트로 변환
|
| 6 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 7 |
+
libreoffice-writer \
|
| 8 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 9 |
+
|
| 10 |
COPY requirements.txt .
|
| 11 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 12 |
|
app.py
CHANGED
|
@@ -283,11 +283,21 @@ def _ext_hwpx(path: Path) -> str:
|
|
| 283 |
return re.sub(r"\n{3,}", "\n\n", text).strip()
|
| 284 |
|
| 285 |
|
| 286 |
-
def _ext_hwp() -> str:
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 291 |
|
| 292 |
|
| 293 |
def _ext_docx(path: Path) -> str:
|
|
@@ -330,7 +340,7 @@ async def extract_file(file: UploadFile = File(...)):
|
|
| 330 |
if ext == ".hwpx":
|
| 331 |
text = _ext_hwpx(tmp_path)
|
| 332 |
elif ext == ".hwp":
|
| 333 |
-
text = _ext_hwp()
|
| 334 |
elif ext == ".docx":
|
| 335 |
text = _ext_docx(tmp_path)
|
| 336 |
elif ext == ".pdf":
|
|
|
|
| 283 |
return re.sub(r"\n{3,}", "\n\n", text).strip()
|
| 284 |
|
| 285 |
|
| 286 |
+
def _ext_hwp(path: Path) -> str:
|
| 287 |
+
import subprocess
|
| 288 |
+
import tempfile
|
| 289 |
+
with tempfile.TemporaryDirectory() as tmpdir:
|
| 290 |
+
r = subprocess.run(
|
| 291 |
+
["libreoffice", "--headless", "--norestore",
|
| 292 |
+
"--convert-to", "txt:Text",
|
| 293 |
+
"--outdir", tmpdir, str(path)],
|
| 294 |
+
capture_output=True, text=True, timeout=60,
|
| 295 |
+
env={**os.environ, "HOME": "/tmp"},
|
| 296 |
+
)
|
| 297 |
+
txt = Path(tmpdir) / (path.stem + ".txt")
|
| 298 |
+
if not txt.exists():
|
| 299 |
+
raise RuntimeError(f"HWP → 텍스트 변환 실패\n{r.stderr[:300]}")
|
| 300 |
+
return _ext_txt(txt)
|
| 301 |
|
| 302 |
|
| 303 |
def _ext_docx(path: Path) -> str:
|
|
|
|
| 340 |
if ext == ".hwpx":
|
| 341 |
text = _ext_hwpx(tmp_path)
|
| 342 |
elif ext == ".hwp":
|
| 343 |
+
text = _ext_hwp(tmp_path)
|
| 344 |
elif ext == ".docx":
|
| 345 |
text = _ext_docx(tmp_path)
|
| 346 |
elif ext == ".pdf":
|