aiaiteam Claude Sonnet 4.6 commited on
Commit
ad564ea
·
1 Parent(s): f9b3251

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>

Files changed (2) hide show
  1. Dockerfile +5 -0
  2. 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
- raise RuntimeError(
288
- ".hwp 바이너리 형식은 웹에서 지원되지 않습니다.\n"
289
- "파일을 한글 프로그램에서 .hwpx 또는 .docx로 저장 후 다시 업로드하세요."
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":