| | |
| | | } |
| | | WANT = ['èªå¼å§å»ºè®¾ç´¯è®¡', 'æ¬å¹´è®¡åæèµ', 'èªå¹´å累计', 'æ¬æå®æ', 'å»ºè®¾é¶æ®µ', '形象è¿åº¦'] |
| | | NUMF = ['æ»æèµ', 'èªå¼å§å»ºè®¾ç´¯è®¡', 'æ¬å¹´è®¡åæèµ', 'èªå¹´å累计', 'æ¬æå®æ'] |
| | | CITY17 = ('æ¦æ±', 'é»ç³', 'åå °', '宿', 'è¥é³', 'éå·', 'èé¨', 'åæ', 'èå·', 'é»å', |
| | | 'å¸å®', 'éå·', 'æ©æ½', '仿¡', 'æ½æ±', '天é¨', 'ç¥åæ¶') |
| | | GROUP_PAT = re.compile(r'^(ä¸|äº|ä¸|å|äº|å
|ä¸|å
«)ã') |
| | | SKIP_PAT = re.compile(r'^(å°\s*计|å\s*计|æ»\s*计)$') |
| | | |
| | |
| | | s = s[:-2] |
| | | s = s.rstrip('.ã-') |
| | | return s |
| | | |
| | | |
| | | def normname2(s): |
| | | """æèµç³»ç»æ¯å¯¹ä¸ç¨ï¼å¨ normname åºç¡ä¸å廿é´éå·ç纯è£
饰å符ã""" |
| | | for ch in ('·', 'ï¼', 'â¢', 'âª', 'â', '.', '-'): |
| | | s = str(s or '').replace(ch, '') |
| | | return normname(s) |
| | | |
| | | |
| | | def to_num(v): |
| | |
| | | return out, period |
| | | |
| | | |
| | | def normname3(s): |
| | | """å廿æ¬å·åå
¶å
容ï¼ç¨äºè¯å«ãåç§°å¤äºæ¬æ³¨ãçåä¸é¡¹ç®ï¼ã""" |
| | | t = normname(s) |
| | | t = re.sub(r'\([^)]*\)', '', t) |
| | | for ch in ('·', 'ï¼', 'â¢', 'â', '-', '.', '·'): |
| | | t = t.replace(ch, '') |
| | | return t |
| | | |
| | | |
| | | def best_name_hint(key, tkeys, cutoff=0.80): |
| | | """å¨ç®æ 表项ç®åéæ¾ä¸ key æåçä¸ä¸ªï¼å®½æ¾/廿¬æ³¨ä¸¤ç§å£å¾åæä¼ï¼ã |
| | | |
| | | è¿å (ç®æ 表项ç®å, ç¸ä¼¼åº¦)ï¼æ¾ä¸å°è¿å (None, 0)ã |
| | | """ |
| | | best = (None, 0.0) |
| | | for normf in (lambda s: normname(s, loose=True), normname3): |
| | | base = normf(key) |
| | | table = [normf(x) for x in tkeys] |
| | | hit = difflib.get_close_matches(base, table, n=1, cutoff=cutoff) |
| | | if hit: |
| | | ratio = difflib.SequenceMatcher(None, base, hit[0]).ratio() |
| | | if ratio > best[1]: |
| | | best = (tkeys[table.index(hit[0])], ratio) |
| | | return best |
| | | |
| | | |
| | | def sys_lookup(key, table): |
| | | """卿èµç³»ç»åå
¸éæ¾é¡¹ç®ï¼å
精确ï¼å«å»é´éå·ï¼ï¼å宽æ¾+ç¸ä¼¼åº¦ï¼>=0.90ï¼ã |
| | | |
| | | è¿å (è®°å½, 说æ)ï¼æ¾ä¸å°è¿å (None, '')ã |
| | | """ |
| | | if not table: |
| | | return None, '' |
| | | s = table.get(key) |
| | | if s: |
| | | return s, '' |
| | | for kk, vv in table.items(): |
| | | if normname2(kk) == normname2(key): |
| | | return vv, 'åç§°åæ³ä¸åï¼æèµç³»ç»ï¼%sï¼' % vv['项ç®åç§°'] |
| | | idx = {} |
| | | for kk in table: |
| | | idx.setdefault(normname2(kk), []).append(kk) |
| | | cands = difflib.get_close_matches(normname2(key), list(idx.keys()), n=1, cutoff=0.90) |
| | | if cands: |
| | | kk = idx[cands[0]][0] |
| | | return table[kk], 'åç§°åæ³ä¸åï¼æèµç³»ç»ï¼%sï¼' % table[kk]['项ç®åç§°'] |
| | | return None, '' |
| | | |
| | | |
| | | def find_system_files(indir, ym): |
| | | """å¨è¾å
¥ç®å½éæ¾ãæ¬æ/䏿ãæèµç³»ç»æ¥è¯¢ç»æãæä»¶åæãæ¶æãåéçå¹´æé½è®¤ã""" |
| | | found = {} |
| | |
| | | rep.append('> åªè¯»ï¼æ¬æ¥éª¤ä¸æ¹ä»»ä½æä»¶ï¼è¾åºçãåæ´æ¸
åãä¾ãåå
¥ä¾§ãæ§è¡ã') |
| | | rep.append('') |
| | | changes = [] |
| | | alerts = [] |
| | | |
| | | def add_alert(level, kind, cat, city, name, src, detail, action): |
| | | alerts.append(dict(级å«=level, ç±»å=kind, åç±»=cat, å¸å·=city, 项ç®åç§°=name, |
| | | æ¥æº=src, 详æ
=detail, 建议å¨ä½=action)) |
| | | |
| | | # æºæä»¶è§£ææ ¡éªï¼ç± å¸å·ææ¥è§£æ.py 产åºï¼ |
| | | checks = [] |
| | | p_ck = os.path.join(out, 'è§£ææ ¡éª_%s.tsv' % a.month) |
| | | if os.path.exists(p_ck): |
| | | _lines = io.open(p_ck, encoding='utf-8-sig').read().splitlines() |
| | | if _lines: |
| | | _ckc = _lines[0].split('\t') |
| | | for _ln in _lines[1:]: |
| | | _v = _ln.split('\t') |
| | | _v += [''] * (len(_ckc) - len(_v)) |
| | | checks.append(dict(zip(_ckc, _v))) |
| | | |
| | | # æèµç³»ç»æä»¶ï¼æ¬æ / ä¸æï¼ |
| | | indir = os.path.join(a.root, 'è¾å
¥') |
| | |
| | | rep.append('| ä¸æï¼æ ¡éªåºæ°ï¼ | %s | %d |' % (os.path.basename(pre_path) if pre_path else '**æªæ¾å°ï¼ç¨æ·å£å¾ aï¼éæ¯ææ¾ä¸ä»½ï¼**', len(cur_pre))) |
| | | rep.append('') |
| | | |
| | | # ââ å¼¹çªè§åï¼æèµç³»ç»æä»¶ç¼ºå¤± / æºæä»¶è§£æå¼å¸¸ / æºæä»¶å
é¨å¯¹ä¸ä¸ ââ |
| | | if not cur_path: |
| | | add_alert('黿', 'ç¼ºæ¬ææèµç³»ç»è¡¨', '', '', '', os.path.basename(indir), |
| | | 'æªå¨ãè¾å
¥ãç®å½æ¾å° %s çæèµç³»ç»æ¥è¯¢ç»æ' % a.month, |
| | | 'ææ¬ææèµç³»ç»å¯¼åºçãæ¨¡æ¿_æ¥è¯¢ç»æãæ¾è¿ docs\\æèµ\\è¾å
¥\\ åéè·') |
| | | if not pre_path: |
| | | add_alert('è¦å', 'ç¼ºä¸ææèµç³»ç»è¡¨', '', '', '', os.path.basename(indir), |
| | | 'æªæ¾å° %s çæèµç³»ç»æ¥è¯¢ç»æ â æåº¦æ ¡éªï¼æ¬æèªå¹´å累计 = 䏿èªå¹´å累计 + æ¬æå®æï¼æ æ³æ§è¡' % prev_ym(a.month), |
| | | 'æ¯ææä¸æãæ¬æä¸¤ä»½æèµç³»ç»æ¥è¯¢ç»æé½æ¾è¿ docs\\æèµ\\è¾å
¥\\') |
| | | if not checks: |
| | | add_alert('黿', 'ç¼ºæºæä»¶è§£ææ ¡éª', '', '', '', os.path.basename(p_ck), |
| | | 'æªæ¾å°ãè§£ææ ¡éªãæ¸
åï¼æ æ³å¤ææºæä»¶æ¯å¦èªæ´½ãæ¯å¦è§£æå¤±è´¥', |
| | | 'å
è· å¸å·ææ¥è§£æ.py --month %s' % a.month) |
| | | for ck in checks: |
| | | st = ck.get('ç¶æ', 'OK') |
| | | if st and st != 'OK': |
| | | add_alert('黿' if st.startswith('è§£æå¤±è´¥') else 'è¦å', 'æºæä»¶è§£æå¼å¸¸', |
| | | ck.get('åç±»', ''), ck.get('å¸å·', ''), '', ck.get('æä»¶', ''), |
| | | st, '人工æå¼æºæä»¶ç¡®è®¤è¡¨å¤´/æ°æ®ï¼å¿
è¦æ¶ç»è®°ç¹ä¾åå导å
¥') |
| | | elif ck.get('ä¸è´æ§', '') == 'â ï¸ ä¸ä¸è´': |
| | | add_alert('è¦å', 'æºæä»¶å
é¨å¯¹ä¸ä¸', ck.get('åç±»', ''), ck.get('å¸å·', ''), '', ck.get('æä»¶', ''), |
| | | '项ç®è¡æ±å %s/%s/%s â %s è¡å计 %s/%s/%s' % ( |
| | | ck.get('æ±å_èªå¼å§å»ºè®¾ç´¯è®¡', ''), ck.get('æ±å_èªå¹´å累计', ''), ck.get('æ±å_æ¬æå®æ', ''), |
| | | ck.get('å计è¡', ''), ck.get('å计_èªå¼å§å»ºè®¾ç´¯è®¡', ''), |
| | | ck.get('å计_èªå¹´å累计', ''), ck.get('å计_æ¬æå®æ', '')), |
| | | '让å¸å·æ ¸å¯¹æºæä»¶ï¼åè®¡è¡æé¡¹ç®è¡æéï¼ï¼ç¡®è®¤åå导å
¥') |
| | | |
| | | for cat, spec in TARGETS.items(): |
| | | rep.append('## %s ââ ç®æ æç»è¡¨' % cat) |
| | | rep.append('') |
| | | if not os.path.exists(spec['path']): |
| | | rep.append('ç®æ 表ä¸åå¨ï¼%s' % spec['path']); rep.append(''); continue |
| | | rep.append('ç®æ 表ä¸åå¨ï¼%s' % spec['path']); rep.append('') |
| | | add_alert('黿', 'ç¼ºç®æ æç»è¡¨', cat, '', '', spec['path'], |
| | | 'ç®æ æç»è¡¨ä¸åå¨ï¼æ¬å£åº¦è¯¥åç±»æ æ³åå
¥', 'ææ¨¡æ¿è¡¨æ¾å° docs\\æèµ\\è¾åº\\') |
| | | continue |
| | | tgt = read_target(spec) |
| | | prow = [r for r in parsed if r['åç±»'] == cat] |
| | | tmap = {} |
| | |
| | | loose_tgt = {} |
| | | for k in tmap: |
| | | loose_tgt.setdefault(normname(k, loose=True), []).append(k) |
| | | plain_tgt = {} |
| | | for k in tmap: |
| | | plain_tgt.setdefault(normname3(k), []).append(k) |
| | | tkeys = list(tmap.keys()) |
| | | new_in_src, suspicious = [], [] |
| | | for k in raw_new: |
| | | nl = normname(k, loose=True) |
| | | if nl in loose_tgt: |
| | | suspicious.append((k, loose_tgt[nl][0], '宽æ¾çä»·ï¼å»æ¬å·/å»â项ç®âäºååç¸åï¼')) |
| | | continue |
| | | n3 = normname3(k) |
| | | if n3 and n3 in plain_tgt: |
| | | suspicious.append((k, plain_tgt[n3][0], 'å»ææ¬æ³¨ä¸é´éå·åç¸å')) |
| | | continue |
| | | close = difflib.get_close_matches(nl, [normname(x, loose=True) for x in tkeys], n=1, cutoff=0.90) |
| | | if close: |
| | |
| | | rep.append('- **çä¼¼åä¸é¡¹ç®ãé人工确认** **%d**ï¼æç¨æ·å£å¾ï¼**ä¸èªå¨æ°å¢ãä¸å¨åç§°ï¼å¼¹çªæç¤º**ï¼' % len(suspicious)) |
| | | rep.append('- ç®æ 表æä½æ¬ææºæä»¶æ²¡æï¼ä¿æåå¼ï¼**%d**' % len(only_tgt)) |
| | | rep.append('') |
| | | for k1, hit1, why1 in suspicious: |
| | | _p1 = pmap[k1][0] |
| | | add_alert('è¦å', 'çä¼¼åä¸é¡¹ç®ï¼åç§°åæ³ä¸åï¼', cat, _p1.get('å¸å·', ''), _p1['项ç®åç§°'], |
| | | os.path.basename(_p1['æä»¶']), |
| | | 'ä¸ç®æ 表已æé¡¹ç®ã%sã%s' % (tmap[hit1][0]['项ç®åç§°'], why1), |
| | | '人工确认æ¯å¦åä¸é¡¹ç®ï¼æ¯ â 䏿¹åç§°ãææèµç³»ç»åç§°æ´æ°ï¼å¦ â æ´è¡æ°å¢') |
| | | if suspicious: |
| | | rep.append('### â ï¸ çä¼¼åä¸é¡¹ç®ä½åç§°åæ³ä¸å â é人工确认ï¼ç¨åºä¸èªå¨åå¹¶ãä¹ä¸é夿°å¢ï¼') |
| | | rep.append('') |
| | |
| | | rep.append('') |
| | | rep.append('| 项ç®åç§° | æ¥æºæä»¶ | èªå¼å§å»ºè®¾ç´¯è®¡ | èªå¹´å累计 | æ¬æå®æ | åç§°ç¸ä¼¼åº¦æç¤º |') |
| | | rep.append('| --- | --- | --- | --- | --- | --- |') |
| | | loose_keys = [normname(x, loose=True) for x in tkeys] |
| | | for k in new_in_src: |
| | | p0 = pmap[k][0] |
| | | nl = normname(k, loose=True) |
| | | close = difflib.get_close_matches(nl, loose_keys, n=1, cutoff=0.80) |
| | | hint = '' |
| | | if close: |
| | | hit = tkeys[loose_keys.index(close[0])] |
| | | hint = 'â ï¸ ä¸ã%sãç¸ä¼¼ %.2fï¼è¯·ç¡®è®¤æ¯å¦åä¸é¡¹ç®' % ( |
| | | hit, difflib.SequenceMatcher(None, nl, close[0]).ratio()) |
| | | _hit, _r = best_name_hint(k, tkeys) |
| | | hint = ('â ï¸ ä¸ã%sãç¸ä¼¼ %.2fï¼è¯·ç¡®è®¤æ¯å¦åä¸é¡¹ç®' % (_hit, _r)) if _hit else '' |
| | | _sim = hint |
| | | add_alert('æç¤º', 'å°æ°å¢é¡¹ç®', cat, p0.get('å¸å·', ''), p0['项ç®åç§°'], |
| | | os.path.basename(p0['æä»¶']), |
| | | 'ç®æ 表没æè¿ä¸ªé¡¹ç®ï¼èªå¼å§å»ºè®¾ç´¯è®¡/èªå¹´å累计/æ¬æå®æ = %s/%s/%s%s' % ( |
| | | p0.get('èªå¼å§å»ºè®¾ç´¯è®¡', ''), p0.get('èªå¹´å累计', ''), p0.get('æ¬æå®æ', ''), |
| | | ('ï¼' + hint) if hint else ''), |
| | | '确认æ¯ç宿°é¡¹ç®ååå
¥ï¼æ´è¡æå
¥ï¼å¤å¶ç¸é»è¡æ ¼å¼ï¼') |
| | | rep.append('| %s | %s | %s | %s | %s | %s |' % ( |
| | | p0['项ç®åç§°'], os.path.basename(p0['æä»¶'])[:30], p0.get('èªå¼å§å»ºè®¾ç´¯è®¡', ''), |
| | | p0.get('èªå¹´å累计', ''), p0.get('æ¬æå®æ', ''), hint)) |
| | |
| | | '项ç®åç§°': p['项ç®åç§°'], 'åå
¥æ¥æº': os.path.basename(p['æä»¶']), |
| | | **{c: p.get(c, '') for c in WANT}}) |
| | | |
| | | # ç®æ 表æãæ¬ææºæä»¶æ²¡æ â ä¿æåå¼ï¼æç¤ºï¼ä¸é»æï¼ |
| | | if only_tgt: |
| | | _names = [tmap[k][0]['项ç®åç§°'] for k in only_tgt] |
| | | add_alert('æç¤º', 'æ¬ææºæä»¶éæ²¡æç项ç®', cat, '', '', 'â', |
| | | 'ç®æ è¡¨éæ %d ä¸ªé¡¹ç®æ¬æå¸å·ææ¥æ²¡æ¥ï¼%s%s' % ( |
| | | len(_names), 'ã'.join(_names[:8]), ' ç' if len(_names) > 8 else ''), |
| | | 'æå£å¾ä¿æä¸æåå¼ï¼è¥å¸å·ç¡®å®å·²å建ï¼è¯·äººå·¥ç¡®è®¤æ¯å¦ä¿ç') |
| | | |
| | | # 䏿¹æ°å¼æ¯å¯¹ï¼æºæä»¶ vs æèµç³»ç»ï¼æ¬æï¼ |
| | | if cur_sys: |
| | | diff, missing = [], [] |
| | | diff, missing, shifted = [], [], [] |
| | | for k in matched: |
| | | p, t = pmap[k][0], tmap[k][0] |
| | | s = cur_sys.get(k) |
| | | s, note = sys_lookup(k, cur_sys) |
| | | if not s: |
| | | missing.append(t['项ç®åç§°']) |
| | | continue |
| | | for c in ('èªå¼å§å»ºè®¾ç´¯è®¡', 'èªå¹´å累计', 'æ¬æå®æ'): |
| | | if note: |
| | | add_alert('æç¤º', 'æèµç³»ç»åç§°åæ³ä¸å', cat, p.get('å¸å·', ''), t['项ç®åç§°'], |
| | | os.path.basename(p['æä»¶']), note + 'ï¼å·²ææèµç³»ç»è¿æ¡è®°å½åæ°å¼å¯¹ç
§ï¼é¡¹ç®åç§°ä¸å¨ï¼', |
| | | 'ç¥æå³å¯') |
| | | for c in ('æ»æèµ', 'èªå¼å§å»ºè®¾ç´¯è®¡', 'æ¬å¹´è®¡åæèµ', 'èªå¹´å累计', 'æ¬æå®æ'): |
| | | pv, sv = to_num(p.get(c)), s.get(c) |
| | | if pv is None or sv is None: |
| | | continue |
| | | if abs(pv - sv) > 0.05: |
| | | diff.append((t['项ç®åç§°'], c, pretty(pv), pretty(sv), pretty(sv - pv))) |
| | | if abs(pv - sv) <= 0.05: |
| | | continue |
| | | diff.append((t['项ç®åç§°'], c, pretty(pv), pretty(sv), pretty(sv - pv))) |
| | | if abs(pv - sv) > 1.0: |
| | | add_alert('è¦å', 'æºæä»¶ä¸æèµç³»ç»ä¸ä¸è´', cat, p.get('å¸å·', ''), t['项ç®åç§°'], |
| | | os.path.basename(p['æä»¶']), |
| | | '%sï¼å¸å·ææ¥ %s ï¼ æèµç³»ç» %sï¼å·® %sï¼' % (c, pretty(pv), pretty(sv), pretty(sv - pv)), |
| | | '人工确认以åªä¸ªä¸ºåï¼è¥æ¯ååéä½å修解æè§ååéè·') |
| | | for c2 in ('æ»æèµ', 'èªå¼å§å»ºè®¾ç´¯è®¡', 'æ¬å¹´è®¡åæèµ', 'èªå¹´å累计', 'æ¬æå®æ'): |
| | | if c2 == c: |
| | | continue |
| | | sv2 = s.get(c2) |
| | | if sv2 is not None and abs(pv - sv2) <= 0.05: |
| | | shifted.append((t['项ç®åç§°'], c, c2)) |
| | | add_alert('è¦å', 'çä¼¼ååéä½', cat, p.get('å¸å·', ''), t['项ç®åç§°'], |
| | | os.path.basename(p['æä»¶']), |
| | | 'å¸å·ææ¥ã%sã= %sï¼æ°å¥½çäºæèµç³»ç»ã%sã' % (c, pretty(pv), c2), |
| | | 'æ£æ¥æºæä»¶è¡¨å¤´ï¼ç»è¡¨å¤´åå¹¶åå
æ ¼æå®¹æéä½ï¼ï¼ä¿®ååè§ååéè·è§£æ') |
| | | rep.append('') |
| | | rep.append('### æºæä»¶ vs æèµç³»ç»ï¼æ¬æï¼ï¼**æ°å¼ä¸ä¸è´ %d å¤**ï¼éå¼¹çªæç¤ºï¼' % len(diff)) |
| | | rep.append('### æºæä»¶ vs æèµç³»ç»ï¼æ¬æï¼ï¼**æ°å¼ä¸ä¸è´ %d å¤**ï¼éå¼¹çªæç¤ºï¼ï¼å
¶ä¸çä¼¼ååéä½ **%d** å¤' % (len(diff), len(shifted))) |
| | | rep.append('') |
| | | if diff: |
| | | rep.append('| 项ç®åç§° | åæ®µ | å¸å·ææ¥ | æèµç³»ç» | å·®é¢ |') |
| | |
| | | for nm1 in missing[:60]: |
| | | rep.append('- %s' % nm1) |
| | | rep.append('') |
| | | for nm1 in missing: |
| | | add_alert('æç¤º', 'æèµç³»ç»æ¥æ æ¤é¡¹ç®', cat, '', nm1, 'â', |
| | | 'æèµç³»ç»æ¬ææ¥è¯¢ç»æé没æè¿ä¸ªé¡¹ç®åç§°', 'ç¥æå³å¯ï¼å¦é以æèµç³»ç»ä¸ºåï¼è¯·äººå·¥æ ¸å¯¹åç§°') |
| | | |
| | | # æåº¦æ ¡éªï¼æ¬æèªå¹´å累计 = 䏿èªå¹´å累计 + æ¬æå®æ |
| | | if cur_pre: |
| | |
| | | p, t = pmap[k][0], tmap[k][0] |
| | | nowj = to_num(p.get('èªå¹´å累计')) |
| | | nowk = to_num(p.get('æ¬æå®æ')) |
| | | pre = cur_pre.get(k) |
| | | pre, _note = sys_lookup(k, cur_pre) |
| | | if nowj is None or nowk is None or not pre: |
| | | continue |
| | | prej = pre.get('èªå¹´å累计') |
| | |
| | | continue |
| | | if abs(nowj - (prej + nowk)) > 0.05: |
| | | bad.append((t['项ç®åç§°'], pretty(prej), pretty(nowk), pretty(nowj), pretty(prej + nowk))) |
| | | add_alert('è¦å', 'æåº¦çå¼ä¸ç¬¦', cat, p.get('å¸å·', ''), t['项ç®åç§°'], |
| | | '%s + %s = %sï¼èæ¬æèªå¹´åç´¯è®¡æ¯ %sï¼å·® %sï¼' % ( |
| | | pretty(prej), pretty(nowk), pretty(prej + nowk), pretty(nowj), |
| | | pretty(nowj - prej - nowk)), |
| | | 'åå
¥æ¶æçå¼çº æ£ä¸º %sï¼å¹¶è®©å¸å·ç¡®è®¤' % pretty(prej + nowk)) |
| | | rep.append('### æåº¦æ ¡éªãæ¬æèªå¹´å累计 = 䏿èªå¹´å累计 + æ¬æå®æãï¼ä¸ç¬¦ **%d** 项' % len(bad)) |
| | | rep.append('') |
| | | if bad: |
| | |
| | | rep.append('### æåº¦æ ¡éªï¼**è·³è¿**ï¼æªæ¾å°ä¸ææèµç³»ç»æ°æ®è¡¨ï¼æç¨æ·å£å¾ (a) éæ¯ææ¾ä¸ä»½ï¼') |
| | | rep.append('') |
| | | |
| | | # æ¬ææ²¡æä»»ä½é¡¹ç®è¡çå¸å· â æç¤ºï¼å¯è½æ¼æ¥ï¼ |
| | | for cat in TARGETS: |
| | | _cities = {r['å¸å·'] for r in parsed if r['åç±»'] == cat and r['å¸å·']} |
| | | _miss = [c for c in CITY17 if c not in _cities] |
| | | if _miss: |
| | | add_alert('æç¤º', 'æ¬ææ 该å¸å·æ°æ®', cat, '', '', 'â', |
| | | 'å
± %d 个å¸å·æ¬ææ²¡æä»»ä½é¡¹ç®è¡ï¼%s' % (len(_miss), 'ã'.join(_miss)), |
| | | '确认æ¯ã该å¸å·ç¡®å®æ²¡æé¡¹ç®ãè¿æ¯ãæ¼æ¥ãï¼æ¼æ¥å让å¸å·è¡¥æ¥') |
| | | |
| | | # ---- æ±æ»ãå¼¹çªæç¤ºãï¼æªæ¥æ¬è¿ Java åç«¯æ¶ææ¤éæ¡å¼¹çªï¼ ---- |
| | | _lv = {'黿': 0, 'è¦å': 1, 'æç¤º': 2} |
| | | alerts.sort(key=lambda x: (_lv.get(x['级å«'], 9), x['ç±»å'], x['åç±»'], x['å¸å·'], x['项ç®åç§°'])) |
| | | _n = {k: sum(1 for x in alerts if x['级å«'] == k) for k in ('黿', 'è¦å', 'æç¤º')} |
| | | a_cols = ['åºå·', '级å«', 'ç±»å', 'åç±»', 'å¸å·', '项ç®åç§°', 'æ¥æº', '详æ
', '建议å¨ä½'] |
| | | p_al = os.path.join(out, 'å¼¹çªæç¤º_%s.tsv' % a.month) |
| | | with io.open(p_al, 'w', encoding='utf-8-sig') as fh: |
| | | fh.write('\t'.join(a_cols) + '\n') |
| | | for _i, _x in enumerate(alerts, 1): |
| | | fh.write('\t'.join(str(_i) if _k == 'åºå·' else str(_x.get(_k, '')).replace('\t', ' ') |
| | | for _k in a_cols) + '\n') |
| | | al_md = ['## â ï¸ å¼¹çªæç¤ºæ»è§ï¼å
± %d 项ï¼é»æ %d ï¼ è¦å %d ï¼ æç¤º %dï¼' % ( |
| | | len(alerts), _n['黿'], _n['è¦å'], _n['æç¤º']), ''] |
| | | al_md.append('> 级å«ï¼**黿**=ä¸è½å表ï¼å
å¤çï¼**è¦å**=æ°æ®æçç¹ï¼äººå·¥ç¡®è®¤åååï¼**æç¤º**=ä»
åç¥ã') |
| | | al_md.append('> æºå¨å¯è¯»æ¸
åï¼`%s`ï¼æªæ¥ Java/ç½é¡µææ¤éæ¡å¼¹çªï¼ãè§åè§ `docs\\æèµ\\å¼¹çªæç¤ºè§å_2026-09-17.md`ã' |
| | | % os.path.basename(p_al)) |
| | | al_md.append('') |
| | | if alerts: |
| | | al_md.append('| åºå· | çº§å« | ç±»å | åç±» | å¸å· | 项ç®åç§° | 详æ
| 建议å¨ä½ |') |
| | | al_md.append('| --- | --- | --- | --- | --- | --- | --- | --- |') |
| | | for _i, _x in enumerate(alerts, 1): |
| | | al_md.append('| %d | %s | %s | %s | %s | %s | %s | %s |' % ( |
| | | _i, _x['级å«'], _x['ç±»å'], _x['åç±»'], _x['å¸å·'], _x['项ç®åç§°'], _x['详æ
'], _x['建议å¨ä½'])) |
| | | al_md.append('') |
| | | else: |
| | | al_md.append('ï¼æ ï¼æææ£æ¥é¡¹åéè¿ï¼'); al_md.append('') |
| | | rep = rep[:4] + al_md + rep[4:] |
| | | |
| | | cols = ['åç±»', 'å¨ä½', 'ç®æ è¡å·', '项ç®åç§°', 'åå
¥æ¥æº'] + WANT |
| | | p_tsv = os.path.join(out, 'åæ´æ¸
å_%s.tsv' % a.month) |
| | | with io.open(p_tsv, 'w', encoding='utf-8-sig') as fh: |
| | |
| | | p_md = os.path.join(out, 'å¹é
æ ¡éªæ¥å_%s.md' % a.month) |
| | | io.open(p_md, 'w', encoding='utf-8').write('\n'.join(rep) + '\n') |
| | | print('åæ´æ¡æ° = %d' % len(changes)) |
| | | print('å¼¹çªæç¤º = %dï¼é»æ %d / è¦å %d / æç¤º %dï¼' % (len(alerts), _n['黿'], _n['è¦å'], _n['æç¤º'])) |
| | | print('wrote', p_md) |
| | | print('wrote', p_tsv) |
| | | print('wrote', p_al) |
| | | |
| | | |
| | | if __name__ == '__main__': |