Files
Aislo/resources/knowledge/original/_pipeline/extract_zip.py
T
eomsangdonandClaude Opus 5 4cb9b15939 style: 저장소 전체 포맷터 일괄 적용 (prettier·biome·ruff)
파일마다 포맷 폭이 달라(≈80 대 100) 한 줄만 고쳐도 포맷터가 무관한 줄을 대량
재포맷했음. 사용자 지시로 전체를 한 번에 맞춤. 코드 동작 변경 없음 — 포맷만.

- 프론트엔드 `.ts/.css/.html` → 저장소 prettier (`.prettierrc`, printWidth 100)
- `B07_DesignDetail/openwebcad/**` → 자체 biome (tab 들여쓰기·single quote·lineWidth 100).
  `biome format` 만 사용 — `biome lint --write` 는 포맷 아닌 코드 수정까지 하므로 제외
- 파이썬 → `ruff format` (엔진 코드는 이미 정합, resources·scratch 스크립트 24개만 변경)

두 포맷터가 서로 되돌리지 않도록 `.prettierignore` 신규 — openwebcad 와 빌드·산출물
폴더를 prettier 대상에서 뺌. `.prettierrc` 에 `endOfLine: "auto"` 추가 — 기본값 `lf` 가
`core.autocrlf=true` 로 받은 CRLF 파일을 매번 전부 다시 써서 `--list-different` 가
실제 포맷 차이를 가리고 있었음.

검증: `tsc --noEmit` 통과(루트·openwebcad 둘 다), pytest 349 passed / 17 skipped /
0 failed, CAD vitest 87건 중 81 passed / 6 failed(laptop-sub 기준선과 동일, 회귀 없음).
포맷터 재실행 시 prettier·biome 모두 변경 0건.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 07:08:24 +09:00

75 lines
2.1 KiB
Python

# -*- coding: utf-8 -*-
"""첨부 zip 압축해제 + 문서화.
- zip 내 CP949(EUC-KR) 파일명 mojibake를 복원해 `첨부/[zip]<이름>/` 에 해제
- 내부 HWP/HWPX → md 변환(hwpx_text.to_md / hwp5_to_md)
"""
import re, sys, zipfile
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import hwpx_text
ROOT = Path(__file__).resolve().parent.parent
def fixname(n):
"""zip 엔트리명 CP437 mojibake → CP949 복원."""
try:
return n.encode("cp437").decode("cp949")
except Exception:
return n
def safe_part(s):
return re.sub(r'[:*?"<>|]', "_", s).strip()
def extract_one(zip_path):
zf = zipfile.ZipFile(zip_path)
dest = zip_path.parent / ("[압축] " + zip_path.stem)
dest.mkdir(exist_ok=True)
n = 0
for info in zf.infolist():
if info.is_dir():
continue
rel = "/".join(safe_part(p) for p in fixname(info.filename).split("/"))
out = dest / rel
out.parent.mkdir(parents=True, exist_ok=True)
with zf.open(info) as src:
out.write_bytes(src.read())
n += 1
return dest, n
def convert_dir(folder):
ok = fail = 0
for f in sorted(folder.rglob("*")):
if f.suffix.lower() not in (".hwp", ".hwpx"):
continue
md = f.with_suffix(".md")
try:
b = f.read_bytes()[:4]
if b[:2] == b"PK": # HWPX
text = hwpx_text.to_md(f)
elif b.hex() == "d0cf11e0": # 구형 HWP
text = hwpx_text.hwp5_to_md(f)
else:
fail += 1
continue
md.write_text(text, encoding="utf-8")
ok += 1
except Exception as e:
print(f" ! {f.name[:50]} :: {type(e).__name__}")
fail += 1
return ok, fail
if __name__ == "__main__":
zips = [Path(a) for a in sys.argv[1:]] or list(ROOT.rglob("첨부/*.zip"))
for z in zips:
dest, n = extract_one(z)
ok, fail = convert_dir(dest)
print(f"[{z.name}] 해제 {n} / md {ok} 실패 {fail}{dest.name}")