Files
Aislo/docs/raw/M01_고침/sub2/tool.py
T

104 lines
5.0 KiB
Python

# -*- coding: utf-8 -*-
"""28-2b 보조 — 읽기: show/find · 쓰기: set (로직 JSON 에서 그 호표 줄의 요소 글자만 바꿈)."""
import sys, json, re, glob, os, time
sys.stdout.reconfigure(encoding='utf-8')
ROOT = r'C:\Aislo_wt\sub_laptop_2'
MDIR = ROOT + r'\resources\master_data'
sys.path.insert(0, MDIR + r'\scripts')
import check_master as cm
import master_pick as mp
import master_material as mm
M = None
def master():
global M
if M is None: M = cm.master()
return M
def logic_file(key):
for f in glob.glob(MDIR + r'\로직_*.json'):
t = open(f, encoding='utf-8').read()
if '"키": "%s"' % key in t: return f
def logic(key):
f = logic_file(key)
d = json.load(open(f, encoding='utf-8'))
for l in d['줄']:
if l['키'] == key: return f, l
def hits(cond, unit, n=3):
m = master(); rows = m.index.get(mm.MARKET, {})
keys = mp.search(m, cond, {}, unit)
out = []
for k in keys[:n]:
r = rows[k]; out.append('%s %s %s [%s]%s' % (k, r.get('이름'), r.get('규격') or '', r.get('단위'), '' if mm._offers(m, k) else ' (값 없음)'))
return len(keys), out
def show(key):
f, l = logic(key)
print('##', key, l['이름'], os.path.basename(f), '결과단위', l['결과단위'])
for i, h in enumerate(l.get('호표', [])):
if h.get('종류') != '재료': continue
el = h['요소']
cond = el if isinstance(el, dict) else {}
n, hs = hits(cond, h.get('단위')) if cond.get('검색어') else (0, [])
print(' [%d] %s | 단위 %s | 수량 %s | %s' % (i, h['이름'], h.get('단위'), str(h.get('수량'))[:40], json.dumps(el, ensure_ascii=False)))
print(' -> %d건: %s' % (n, ' // '.join(hs)))
for j, x in enumerate(l.get('덧줄', [])):
if re.search(r'MT\d{6}', json.dumps(x, ensure_ascii=False)): print(' 덧줄[%d]' % j, json.dumps(x, ensure_ascii=False)[:200])
def find(words, gubun=None, sub=None, n=25):
m = master(); rows = m.index.get(mm.MARKET, {})
cond = {'검색어': words}
if gubun: cond['구분'] = gubun
if sub: cond['상세구분'] = sub
keys = mp.search(m, cond, {}, None)
print('총', len(keys))
for k in keys[:n]:
r = rows[k]; print(k, r.get('구분'), '/', r.get('상세구분'), '|', r.get('이름'), '|', r.get('규격') or '', '|', r.get('단위'), '' if mm._offers(m, k) else '(값 없음)')
def set_(key, idx, term, gubun=None, sub=None, expect=None):
f, l = logic(key)
h = l['호표'][int(idx)]
assert h['종류'] == '재료', h
old = h['요소']
new = dict(old)
new['검색어'] = term
if gubun is not None: new['구분'] = gubun
if sub is not None: new['상세구분'] = sub
t = open(f, encoding='utf-8', newline='').read()
nl = '\r\n' if '\r\n' in t else '\n'
# 그 로직 블록 안, 그 호표 줄의 요소 글자만 바꿈
start = t.index('"키": "%s"' % key)
nxt = t.find('"키": "G', start + 10)
end = nxt if nxt > 0 else len(t)
block = t[start:end]
oldtxt = json.dumps(old, ensure_ascii=False)
# 파일은 한 줄씩 들여쓴 JSON — 요소 dict 를 찾아 바꿈(들여쓰기 그대로)
pat = re.compile(r'"요소": \{[^{}]*\}')
cands = [m_ for m_ in pat.finditer(block) if json.loads(m_.group(0)[len('"요소": '):]) == old]
if len(cands) < 1: raise SystemExit('요소 글자를 못 찾음 ' + oldtxt)
# 같은 요소가 여럿이면 호표 순서로 idx 를 세어 고름
all_jyo = [m_ for m_ in pat.finditer(block)]
hopyo = [i for i, x in enumerate(l['호표']) if isinstance(x['요소'], dict)]
order = hopyo.index(int(idx))
target = all_jyo[order]
assert json.loads(target.group(0)[len('"요소": '):]) == old, ('순서 어긋남', target.group(0)[:100])
# 원본 글자 모양(한 줄/여러 줄) 유지: 같은 형식으로 dump
g0 = target.group(0)
body = g0[len('"요소": '):]
if '\n' in body: raise SystemExit('여러 줄 요소 — 손으로')
sep = ', ' if ', ' in body else ','
keys = list(old.keys())
for k in ('구분', '상세구분', '검색어'):
if k in new and k not in keys: keys.append(k)
newbody = '{' + sep.join('"%s": %s' % (k, json.dumps(new[k], ensure_ascii=False)) for k in keys) + '}'
if ': ' not in body: newbody = newbody.replace('": ', '":')
block2 = block[:target.start()] + '"요소": ' + newbody + block[target.end():]
t2 = t[:start] + block2 + t[end:]
open(f, 'w', encoding='utf-8', newline='').write(t2)
global M; M = None
f2, l2 = logic(key); h2 = l2['호표'][int(idx)]
n, hs = hits(h2['요소'], h2.get('단위'))
print('고침', key, idx, h2['이름'], '->', json.dumps(h2['요소'], ensure_ascii=False))
print(' 검색 %d건 첫째: %s' % (n, hs[0] if hs else '없음'))
if expect: print(' 기대 %s %s' % (expect, 'OK' if hs and hs[0].split()[0] == expect else '★ 다름'))
if __name__ == '__main__':
a = sys.argv[1:]
if a[0] == 'show': [show(k) for k in a[1:]]
elif a[0] == 'find': find(a[1], *(a[2:4]))
elif a[0] == 'set': set_(a[1], a[2], a[3], *(a[4:7]))