공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
88 lines
4.3 KiB
Python
88 lines
4.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
CMS-한정 콘텐츠탭 일괄 검증(읽기전용). _tab_scan_cms.scan() 을 미검수 시군에 돌려
|
|
사이트별 탭그룹/예상추가행 리포트 생성. 수정 일절 안 함.
|
|
리포트: _temp/_tab_rescan_report.{md,json}
|
|
"""
|
|
import sys, os, json, glob, traceback
|
|
sys.stdout.reconfigure(encoding='utf-8')
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
from _tab_scan_cms import scan
|
|
|
|
BASE = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '광역_사이트맵'))
|
|
REGIONS = ['충청남도', '충청북도', '전북특별자치도', '제주특별자치도']
|
|
# 검수완료(손대지 않음) + 서천(이미 전개됨) 제외
|
|
SKIP = {'계룡', '공주', '금산', '논산', '보령', '당진', '부여', # 충남 검수완료
|
|
'고창', '군산', '김제', '남원', '무주', # 전북 검수완료
|
|
'서천'} # 이미 전개
|
|
|
|
def org_of(path):
|
|
return os.path.basename(os.path.dirname(path)).split('.', 1)[-1] # "13.청양군" -> "청양군"
|
|
|
|
def main_xlsx(d):
|
|
cands = [f for f in glob.glob(os.path.join(d, '*.xlsx'))
|
|
if '_backup_' not in f and not os.path.basename(f).startswith('~$')]
|
|
return cands[0] if cands else None
|
|
|
|
def discover():
|
|
out = []
|
|
for region in REGIONS:
|
|
for d in sorted(glob.glob(os.path.join(BASE, region, '*'))):
|
|
if not os.path.isdir(d): continue
|
|
org = os.path.basename(d).split('.', 1)[-1]
|
|
if any(s in org for s in SKIP): continue
|
|
x = main_xlsx(d)
|
|
if x: out.append((org, x))
|
|
return out
|
|
|
|
if __name__ == '__main__':
|
|
targets = discover()
|
|
print(f"대상 {len(targets)}곳:", ', '.join(o for o, _ in targets))
|
|
results = []
|
|
for i, (org, x) in enumerate(targets, 1):
|
|
print(f"\n[{i}/{len(targets)}] {org} ...", flush=True)
|
|
try:
|
|
r = scan(x)
|
|
r['org'] = org
|
|
results.append(r)
|
|
print(f" rows={r['rows']} pages={r['pages']} "
|
|
f"page_tab_groups={r['page_tab_groups']} est_new=+{r['est_new']} "
|
|
f"inpage={r['inpage_groups']}", flush=True)
|
|
except Exception as e:
|
|
print(f" ERROR: {e}", flush=True)
|
|
traceback.print_exc()
|
|
results.append({'org': org, 'xlsx': os.path.basename(x), 'error': str(e)})
|
|
|
|
tdir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '_temp'))
|
|
os.makedirs(tdir, exist_ok=True)
|
|
with open(os.path.join(tdir, '_tab_rescan_report.json'), 'w', encoding='utf-8') as f:
|
|
json.dump(results, f, ensure_ascii=False, indent=1)
|
|
|
|
# 마크다운 리포트
|
|
lines = ['# CMS-한정 콘텐츠탭 재스캔 리포트(읽기전용)', '',
|
|
'> `_tab_scan_cms.scan()` 결과. est_new=시트에 없는 탭링크(펼치기 시 추가될 행 추정).',
|
|
'> 숫자는 후보 신호이며 펼치기 전 개별 검토 필요.', '',
|
|
'| 기관 | 행수 | 탭그룹 | 예상+행 | 인페이지탭 | 상태 |',
|
|
'|---|---|---|---|---|---|']
|
|
def stat(r):
|
|
if 'error' in r: return '⚠️ ERROR'
|
|
if r['page_tab_groups'] == 0 and r['inpage_groups'] == 0: return '탭없음(확정0)'
|
|
return '🔴 탭있음(전개대상)'
|
|
for r in sorted(results, key=lambda r: -(r.get('est_new', 0))):
|
|
if 'error' in r:
|
|
lines.append(f"| {r['org']} | - | - | - | - | ⚠️ {r['error'][:30]} |")
|
|
else:
|
|
lines.append(f"| {r['org']} | {r['rows']} | {r['page_tab_groups']} | "
|
|
f"+{r['est_new']} | {r['inpage_groups']} | {stat(r)} |")
|
|
lines += ['', '## 상위 그룹 상세', '']
|
|
for r in sorted(results, key=lambda r: -(r.get('est_new', 0))):
|
|
if r.get('est_new', 0) == 0: continue
|
|
lines.append(f"### {r['org']} (dom={r['dom']}, +{r['est_new']}행 / {r['page_tab_groups']}그룹)")
|
|
for g in r.get('top', []):
|
|
lines.append(f"- R{g['r']} **{str(g['F'])[:18]}** cls=`{g['cls'][:22]}` "
|
|
f"tabs={g['tabs']} missing={g['missing']} ex={g['ex']}")
|
|
lines.append('')
|
|
with open(os.path.join(tdir, '_tab_rescan_report.md'), 'w', encoding='utf-8') as f:
|
|
f.write('\n'.join(lines))
|
|
print(f"\n리포트 저장: {tdir}\\_tab_rescan_report.md / .json")
|