공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
61 lines
3.0 KiB
Python
61 lines
3.0 KiB
Python
# -*- 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')
|