# -*- coding: utf-8 -*-
"""익산 게시판 행 M/N/O/P/Q 수집(행범위 지정). 글수(전체N)·N(이미지규칙+상세top10)·KOGL(open0N+표준+링크, 상세top10).
사용: python -X utf8 _익산_mnopq.py <start> <end> [--write]
"""
import sys, os, re, shutil, importlib.util
from urllib.parse import urljoin
from concurrent.futures import ThreadPoolExecutor, as_completed
import openpyxl

HERE=os.path.dirname(os.path.abspath(__file__))
s=importlib.util.spec_from_file_location('m',os.path.join(HERE,'_jeonbuk_phase234_all.py'))
M=importlib.util.module_from_spec(s); s.loader.exec_module(m if False else M)
sk=importlib.util.spec_from_file_location('k',os.path.join(HERE,'_임실_kogl.py'))
KG=importlib.util.module_from_spec(sk); sk.loader.exec_module(KG)
XLSX=r'D:\01.프로젝트\DB수집\작업파일\광역_사이트맵\전북특별자치도\9.익산시\전북특별자치도_익산시.xlsx'
SESS=M.make_session()
TOT=re.compile(r'전체\s*([\d,]+)|총\s*([\d,]+)\s*건|총\s*게시물\s*([\d,]+)')
DECO=re.compile(r'/common/|move\.png|no[-_]?img|blank|spacer|/ico|/btn|bullet|arrow|/bg|icon|see_btn|/sample|mimetype|/file_|filedown|btn_dir|/open\d',re.I)
EXCL=re.compile(r'한눈에|흐름도|절차도|로고(?!송)|logo(?!song)|아이콘|배너|banner|신문고|relation_item|tracer|headline|copyright|copy_logo|popup|wa_mk|웹접근성|품질인증',re.I)
AUDIO=re.compile(r'\.(?:mp3|wav|m4a|ogg|flac)\b',re.I)
MAPPDF=re.compile(r'pdf|viewer\.html|/map|kakao|daum.*map',re.I)

def real_imgs(body):
    out=[]
    for img in body.find_all('img'):
        src=img.get('src') or ''
        if not src or M.KOGL_IMG_PAT.search(src) or DECO.search(src): continue
        if EXCL.search(src+' '+(img.get('alt') or '')): continue
        out.append(img)
    return out
def media(body):
    txt=len(body.get_text(strip=True))>30
    img=len(real_imgs(body))>0; vid=False
    for ifr in body.find_all('iframe'):
        ss=ifr.get('src') or ''
        if M.YOUTUBE_PAT.search(ss): vid=True
        elif MAPPDF.search(ss): img=True
    if not vid and (body.find('video') or body.find('a',href=M.YOUTUBE_PAT) or M.VIDEO_EXT.search(str(body))): vid=True
    aud=bool(body.find('audio')) or bool(AUDIO.search(str(body)))
    return img,vid,aud,txt
def njoin(t,i,v,a):
    p=[]
    if t:p.append('어문')
    if i:p.append('이미지')
    if v:p.append('영상')
    if a:p.append('오디오')
    return ','.join(p) if p else '없음'

def collect(K):
    soup=None
    for _ in range(3):
        soup=M.fetch(SESS,K)
        if soup is not None: break
    if soup is None: return None
    body=M.get_body(soup,M.BODY_SEL); txt=body.get_text(' ',strip=True)
    mm=TOT.search(txt); Mval=None
    if mm: g=[x for x in mm.groups() if x]; Mval=int(g[0].replace(',',''))
    else:
        el=body.select_one('.total strong,.num,.board_total')
        if el and el.get_text(strip=True).replace(',','').isdigit(): Mval=int(el.get_text(strip=True).replace(',',''))
    img,vid,aud,t=media(body)
    types,qy,qn=KG.kogl(body); P='게시판' if types else ''
    dus=KG.detail_urls(body,K,10)
    empty=bool(re.search(r'게시물이?\s*없|등록된?\s*(?:게시물|자료)\s*가?\s*없',txt))
    if (Mval==0) or (not dus and empty):
        return {'M':0,'N':'없음','O':'미부착','P':'','Q':''}
    for du in dus:
        ds=M.fetch(SESS,du)
        if not ds: continue
        db=M.get_body(ds,M.BODY_SEL)
        i2,v2,a2,t2=media(db); img=img or i2;vid=vid or v2;aud=aud or a2;t=t or t2
        dt,dqy,dqn=KG.kogl(db)
        if dt:
            if not types: P='게시물'
            types|=dt; qy=qy or dqy; qn=qn or dqn
    N=njoin(t,img,vid,aud)
    if types:
        O=','.join('%d유형'%n for n in sorted(types)); Q='Y' if qy else 'N'; P=P or '게시판'
    else: O='미부착'; P='';Q=''
    return {'M':Mval if Mval is not None else 0,'N':N,'O':O,'P':P,'Q':Q}

def main():
    st,en=int(sys.argv[1]),int(sys.argv[2]); write='--write' in sys.argv
    wb=openpyxl.load_workbook(XLSX); ws=wb.active
    jobs=[r for r in range(st,en+1) if isinstance(ws.cell(r,11).value,str) and ws.cell(r,11).value.startswith('http')]
    res={}
    with ThreadPoolExecutor(max_workers=6) as ex:
        futs={ex.submit(collect,ws.cell(r,11).value):r for r in jobs}
        for f in as_completed(futs):
            r=futs[f]
            try: res[r]=f.result()
            except: res[r]=None
    for r in sorted(res):
        o=res[r]
        print('r%d %s'%(r,o))
    if write:
        shutil.copy(XLSX, XLSX.replace('.xlsx','_backup_mnopq전.xlsx'))
        for r,o in res.items():
            if not o: continue
            ws.cell(r,13).value=o['M']; ws.cell(r,14).value=o['N']
            ws.cell(r,15).value=o['O']; ws.cell(r,16).value=o['P']; ws.cell(r,17).value=o['Q']
        wb.save(XLSX); print('적용 %d행'%len([1 for o in res.values() if o]))

if __name__=='__main__': main()
