# -*- coding: utf-8 -*- import openpyxl, glob, os, io, sys sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') def rows(p): ws = openpyxl.load_workbook(p, read_only=True, data_only=True).active return [(i, r) for i, r in enumerate(ws.iter_rows(min_row=3, values_only=True), 3)] def g(r, c): return r[c-1] if len(r) >= c else None N_OK = {'어문','이미지','영상','오디오','글꼴','3D','기타','없음'} files = [] for pat in ['광역_사이트맵/*/*/*.xlsx', '교육청_사이트맵/*/*.xlsx']: for p in glob.glob(pat): b = os.path.basename(p) if 'backup' in b or b.startswith('_') or '복사본' in b or '_____' in b: continue files.append(p) out = ['# 프리랜서2 신규기준 재감사 (읽기전용) — 2026-06-12', '', '정식 파일 %d개 (stray 복사본·_____ 제외).' % len(files), ''] N_bad = []; Ppage = []; site = {}; m0n = {} for p in sorted(files): nm = os.path.basename(p).replace('.xlsx', '') for i, r in rows(p): if not isinstance(g(r, 2), int): continue L = str(g(r, 12) or '').strip(); M = g(r, 13); N = str(g(r, 14) or '').strip(); P = str(g(r, 16) or '').strip() if N and L != '사이트': for t in N.split(','): if t.strip() and t.strip() not in N_OK: N_bad.append((nm, i, N)); break if P == '페이지': Ppage.append((nm, i)) if L == '사이트' and any(g(r, c) not in (None, '') for c in (13, 14, 15, 16, 17)): site[nm] = site.get(nm, 0) + 1 if L == '게시판' and M in (0, '0') and N not in ('없음', ''): m0n[nm] = m0n.get(nm, 0) + 1 out.append('## 🔴 확정 위반 1 — N 8종 밖 값 (%d행)' % len(N_bad)) for nm, i, N in N_bad: out.append('- %s r%d : N=%s' % (nm, i, N)) out.append(' → 동영상→영상 / "N유형"·"4" 등은 O열 값이 N에 오입력(실제 저작물유형으로 정정)') out.append('') out.append('## 🔴 확정 위반 2 — P=페이지 (페이지 마크위치는 게시물) (%d행)' % len(Ppage)) for nm, i in Ppage: out.append('- %s r%d : P 페이지→게시물' % (nm, i)) out.append('') out.append('## 🟠 사이트행 오염 — L=사이트인데 M~Q에 값(대부분 O=미부착) 총 %d행' % sum(site.values())) out.append('규칙#11: 사이트는 뒤 컬럼 전부 공백 → 일괄 blank 가능.') for nm, c in sorted(site.items(), key=lambda z: -z[1]): out.append('- %s : %d행' % (nm, c)) out.append('') out.append('## 🟡 재확인 필요 — 게시판 M=0 & N≠없음 (M0=빈게시판이면 N=없음, 미카운트면 재집계) 총 %d행' % sum(m0n.values())) for nm, c in sorted(m0n.items(), key=lambda z: -z[1]): out.append('- %s : %d행' % (nm, c)) open('_pro2_재감사_보고.md', 'w', encoding='utf-8').write('\n'.join(out)) print('N위반 %d | P=페이지 %d | 사이트오염 %d행(%d기관) | M0N %d행(%d기관)' % (len(N_bad), len(Ppage), sum(site.values()), len(site), sum(m0n.values()), len(m0n))) print('보고서 → 작업파일/_pro2_재감사_보고.md')