Files
Aislo/resources/knowledge/original/_pipeline/fix_law_images.py
T
eomsangdonandClaude Fable 5 81cd7e23c3 feat(knowledge): 도메인 지식저장소 메인 통합 + resources 그룹 체계 재편
knowledge (구 Aislo-law 독립 저장소 → resources/knowledge 이관, 저장소 폐지):
- 법령·행정규칙·표준시방서·교본 원문 + 기술문서 55건 + 실무 분석·종합비교
- 루트 지침 체계: README(지도)·00_운영지침·01_수집지침·02_분석지침·
  03_미결_및_확인사항(교본 충돌 리스트 포함)·04_참조_법령기준_목록
- 기술문서 55건 원문 전수 검증 완료 (사방 설계홍수량 법정 기준 등 반영)
- 정리: CAD·오피스 잔재 142건, 중복 zip 7건(413MB), 빈 폴더 30개 제거

resources 그룹 재편 (이름순 그룹핑):
- app_branding(구 prog_icon.jpg)·app_policies(구 legal)·
  data_global_contours(구 grobal_contours)·data_rainfall_idf_cache(구 wamis_contours)·
  template_2dDrawing(구 dwg_analysis/templete — 오타 교정, 상수·경로 동기화)
- dwg_analysis(분석 완료 1.8GB)·templates(빈 폴더)·templete_calc_cost.xlsx 삭제
- 참조 코드 5파일 경로 수정 + 프론트 재빌드 (구 경로 잔존 0)
- .gitignore: resources 추적 전환, national_contours.gpkg(22GB) 영구 제외
- .env: knowledge 수집용 API 정보 주석 통합 (KCSC·법령센터·조달청 제비율)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 19:14:32 +09:00

82 lines
3.0 KiB
Python

# -*- coding: utf-8 -*-
"""법령 본문 md의 원시 <img src="law.go.kr/..."> 태그를 pic/로 내려받아 md 이미지 참조로 교체.
법령 XML 조문·개정문에 인라인으로 박힌 수식·그림 이미지 처리.
이미지는 각 명칭 폴더의 pic/ 에 저장하고 md에서 ../pic 상대참조.
"""
import re, sys, time, urllib.request
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
UA = {"User-Agent": "Mozilla/5.0"}
# src="URL" 형식과 id="flSeq" 형식(내부 이미지) 모두 처리
IMG = re.compile(r'<img\b([^>]*?)/?>')
SRC = re.compile(r'src="([^"]+)"')
IID = re.compile(r'id="(\d+)"')
EXT = {b"\x89PNG": ".png", b"\xff\xd8\xff": ".jpg", b"GIF8": ".gif",
b"BM": ".bmp", b"II*\x00": ".tif", b"MM\x00*": ".tif"}
def sniff(b):
for sig, ext in EXT.items():
if b.startswith(sig):
return ext
return ".png"
def download(url):
u = url.replace("http://", "https://")
for _ in range(3):
try:
with urllib.request.urlopen(urllib.request.Request(u, headers=UA), timeout=40) as r:
b = r.read()
if b and len(b) > 100:
return b
except Exception:
time.sleep(1.5)
return None
def fix(md_path):
"""md 파일: <img> → pic/ 저장 + ![그림](../pic/..) 참조. 폴더는 명칭 폴더의 pic/."""
text = md_path.read_text(encoding="utf-8")
if "<img" not in text and "</img" not in text:
return 0
# 명칭 폴더 = md가 명칭폴더 바로 아래(현행_/교본시점_/CHANGELOG)면 그 폴더, 별표/첨부면 상위
folder = md_path.parent
picdir = folder / "pic"
seq = [0]
def repl(m):
attrs = m.group(1)
ms = SRC.search(attrs)
mi = IID.search(attrs)
if ms:
url = ms.group(1)
elif mi:
url = f"https://www.law.go.kr/LSW/flDownload.do?flSeq={mi.group(1)}"
else:
return m.group(0)
blob = download(url)
if not blob:
return "〔그림: 다운로드 실패〕"
seq[0] += 1
picdir.mkdir(parents=True, exist_ok=True)
fn = f"{md_path.stem}_img{seq[0]}{sniff(blob)}"
(picdir / fn).write_bytes(blob)
return f"![그림](<pic/{fn}>)"
new = IMG.sub(repl, text)
# 부칙 등에서 여는 태그와 분리돼 남은 고아 닫는 태그 제거(단독 줄/인용줄 포함)
new = re.sub(r'^>?\s*</img>\s*$', ">", new, flags=re.M)
new = new.replace("</img>", "")
if new != text:
md_path.write_text(new, encoding="utf-8")
return seq[0]
if __name__ == "__main__":
mds = list(ROOT.rglob("현행_*.md")) + list(ROOT.rglob("교본시점_*.md")) + list(ROOT.rglob("CHANGELOG.md"))
mds = [m for m in mds if "임도기술교본" not in str(m) and "_pipeline" not in str(m)]
tot = 0
for md in sorted(mds):
n = fix(md)
if n:
tot += n
print(f" {n}{md.parent.parent.name[:30]}/{md.name}")
print(f"\n법령 본문 이미지 {tot}장 → pic/ 로컬화")