Files
Aislo/tools/stmate-test/api_img.py
T
eomsangdonandClaude Opus 5.5 47a04b6df8 feat(stmate-test): REA MCP(Ghidra) 파일 입출력 — JDL 탭 줄·묶음 내보내기·검사 · 구버전→Win8 변환 · 엑셀 역등록 구성 줄 · 자재 집계표 엑셀 · 그림 코드
- JDL 줄 = 탭 구분 + \x05/\x07 덧붙임(검사기 0x504d20 · 고정폭 표는 죽은 고리 — 34 §17.9 바로잡음) · 단가 목록 7종·Main·GongJong 머리·Global.Ini 상수 키 · zip 받기
- 구버전 판 가리기(Chk_Data 0x459280) · 7.x/DOS 표별 필드 대응 · B→X 조건 = 단위 X
- 엑셀 역등록 PRPT「속성」·PRIN「대상」·PROUT「저장」 = PR/RR 줄만 · 원본 BDQTY 4건 일치
- 자재 = 재료비 수량집계표 엑셀 내보내기(주요건설자재현황 시트)
- 그림 코드 = COSTN I 코드 IFORM · SIZE = 그림 클래스 이름
- 지식DB 37번

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-14 15:58:17 +09:00

91 lines
2.7 KiB
Python

# -*- coding: utf-8 -*-
"""그림 코드 끼워 넣기 API — I 코드 목록 · 그림 보기(받기) · 그림 넣기(그림저장).
근거: img_code.py 머리(STmate.Cpm TwM_Boxa 0x514df0 · 0x514bc0 · 0x5155a8)
쓰기는 tools/stmate-test/work_dbf/ 아래만(server.WORK_DBF_ROOT) · 바뀌는 파일은 COSTN.DBF · COSTN.SMT 둘뿐.
"""
from __future__ import annotations
import base64
import pathlib
from urllib.parse import quote
from fastapi import APIRouter, HTTPException
from fastapi.responses import Response
from img_code import get_image, list_images, put_image
from pydantic import BaseModel
from stc_project import safe_name, write_output
from stc_read import Source
router = APIRouter()
EXT = {"TJPEGIMAGE": ".jpg", "TBITMAP": ".bmp", "TICON": ".ico", "TMETAFILE": ".emf"}
def _root() -> pathlib.Path:
import server
return server.WORK_DBF_ROOT
def _src(path: str) -> Source:
try:
return Source(path)
except FileNotFoundError:
raise HTTPException(404, f"경로 없음: {path}")
except ValueError as e:
raise HTTPException(400, str(e))
def _guard(fn, *a, **k):
try:
return fn(*a, **k)
except (ValueError, KeyError) as e:
raise HTTPException(400, str(e))
class ImgReq(BaseModel):
source_path: str
code: str = ""
class ImgPutReq(BaseModel):
source_path: str
code: str
data_b64: str
filename: str
to_jpeg: bool = False
target_folder_name: str = ""
@router.post("/api/img/list")
def img_list(req: ImgReq):
return {"rows": _guard(list_images, _src(req.source_path).files)}
@router.post("/api/img/get")
def img_get(req: ImgReq):
"""그림 바이트 — 브라우저가 못 그리는 꼴(TMETAFILE)은 mime 없이(받기만)."""
data, kind, mime = _guard(get_image, _src(req.source_path).files, req.code)
if not data:
raise HTTPException(404, f"{req.code} 그림 없음")
name = quote(f"{req.code.strip()}{EXT.get(kind, '.bin')}")
head = {"X-Img-Kind": kind or "?", "Content-Disposition": f"inline; filename*=UTF-8''{name}"}
return Response(content=data, media_type=mime or "application/octet-stream", headers=head)
@router.post("/api/img/put")
def img_put(req: ImgPutReq):
"""그림 넣기 → work_dbf/<이름>/ 와 STC(COSTN.DBF · COSTN.SMT 만 바뀜)."""
s = _src(req.source_path)
try:
data = base64.b64decode(req.data_b64.split(",", 1)[-1])
except ValueError:
raise HTTPException(400, "base64 아님")
changed, rep = _guard(put_image, s.files, req.code, data, req.filename, req.to_jpeg)
files = dict(s.files) | changed
res = write_output(
_root(), safe_name(req.target_folder_name or s.path.stem), files, s.names, s.entries
)
return {**res, "report": rep}