"""Волна по китайским/азиатским источникам: форумы, реверс, security-новости. Проверяет кандидатов живыми запросами (лента / список тем), пишет живые в omni/sources_cn.py. Запуск: python tools/wave_cn.py [--apply] """ import sys import time from pathlib import Path import requests ROOT = Path(__file__).resolve().parents[1] OUT = ROOT / "omni" / "sources_cn.py" UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/131.0 Safari/537.36") # name, url, adapter, category, tags, limit CAND = [ ("cn_52pojie", "https://www.52pojie.cn/forum.php?mod=guide&view=new", "html_listing", "forum", ("cn", "reverse", "abuse"), 20), ("cn_nodeseek", "https://www.nodeseek.com/", "html_listing", "forum", ("cn", "hosting"), 20), ("cn_freebuf", "https://www.freebuf.com/", "html_listing", "security", ("cn", "security"), 20), ("cn_seebug", "https://paper.seebug.org/", "html_listing", "security", ("cn", "papers", "security"), 15), ("cn_anquanke", "https://www.anquanke.com/", "html_listing", "security", ("cn", "security"), 20), ("cn_4hou", "https://www.4hou.com/", "html_listing", "security", ("cn", "security"), 15), ("cn_kanxue", "https://bbs.kanxue.com/", "html_listing", "forum", ("cn", "reverse"), 20), ("cn_ithome", "https://www.ithome.com/rss/", "rss", "news", ("cn", "tech"), 20), ("cn_cnbeta", "https://www.cnbeta.com.tw/backend.php", "rss", "news", ("cn", "tech"), 20), ("cn_sspai", "https://sspai.com/feed", "rss", "news", ("cn", "tech"), 15), ("cn_chiphell", "https://www.chiphell.com/forum.php?mod=guide&view=new", "html_listing", "forum", ("cn", "hardware"), 15), ("cn_52pojie_rss", "https://www.52pojie.cn/forum.php?mod=rss", "rss", "forum", ("cn", "reverse"), 15), ("cn_v2ex_rss", "https://www.v2ex.com/index.xml", "rss", "forum", ("cn", "community"), 20), ("cn_linuxdo_rss", "https://linux.do/latest.rss", "rss", "forum", ("cn", "community", "ai"), 20), ("cn_hostloc_rss", "https://hostloc.com/forum.php?mod=rss", "rss", "forum", ("cn", "hosting"), 15), ("cn_baidu_sec", "https://xz.aliyun.com/", "html_listing", "security", ("cn", "security"), 15), ("cn_secfree", "https://www.secfree.com/", "html_listing", "security", ("cn", "security"), 10), ("cn_tttang", "https://tttang.com/", "html_listing", "security", ("cn", "security"), 10), ] def probe(url, adapter="html_listing"): try: r = requests.get(url, headers={"User-Agent": UA}, timeout=18, allow_redirects=True) except Exception as e: return 0, type(e).__name__, 0 if adapter == "rss": n_links = r.text.count("= 30 print("%-18s %-3s links %-5d %s" % (name, code or err, links, "LIVE" if ok else "—")) if ok: live.append((name, url, adapter, cat, tags, lim)) else: dead.append(name) time.sleep(0.8) print("\nживых %d, мёртвых %d" % (len(live), len(dead))) if not apply: print("dry-run: --apply чтобы записать omni/sources_cn.py") return 0 body = ['"""Китайские и азиатские источники (проверены живыми запросами tools/wave_cn.py).', '', 'Форумы реверса/хостинга, security-новости, tech-ленты. Все — публичные списки,', 'без ключей и кук. Подключаются в реестр omni как категории forum/security/news.', '"""', '', 'CN = ['] for name, url, adapter, cat, tags, lim in live: t = ", ".join('"%s"' % x for x in tags) body.append(' {"name": "%s", "category": "%s", "kind": "site", "url": "%s",' ' "adapter": "%s", "tags": (%s), "limit": %d},' % (name, cat, url, adapter, t, lim)) body.append(']') OUT.write_text("\n".join(body) + "\n", encoding="utf-8", newline="\n") print("записано", OUT, "| источников", len(live)) return 0 if __name__ == "__main__": sys.exit(main())