реестр: дедуп источников строго по url (2 падавших теста зелёные); инкрементальный abuse-индекс + tgsearch из предыдущей сессии
Some checks failed
ci / test (3.10) (push) Has been cancelled
ci / test (3.11) (push) Has been cancelled
ci / test (3.12) (push) Has been cancelled

This commit is contained in:
ENI
2026-10-27 01:09:30 +03:00
parent d0fca99dda
commit d0b2187319
7 changed files with 601 additions and 24 deletions

View File

@@ -542,6 +542,13 @@ def main(argv=None):
sp.add_argument("--apply", action="store_true")
sp.set_defaults(fn=cmd_pump)
sp = sub.add_parser("tgsearch", help="найти Telegram-каналы по ключевым словам через свою сессию")
sp.add_argument("queries", help="запросы через запятую")
sp.add_argument("--limit", type=int, default=40, help="каналов на запрос")
sp.add_argument("--min-members", type=int, default=0, help="отсеять мелкие каналы")
sp.add_argument("--apply", action="store_true", help="дописать найденные каналы в data/radar_sources.json")
sp.set_defaults(fn=cmd_tgsearch)
sp = sub.add_parser("keys", help="ключи парсеров из vault: сервисы, счётчики, остывание")
sp.add_argument("--service", default="", help="только один сервис")
sp.add_argument("-v", "--verbose", action="store_true", help="по ключам, масками")
@@ -561,4 +568,58 @@ def main(argv=None):
if __name__ == "__main__":
sys.exit(main())
sys.exit(main())
def cmd_tgsearch(a):
"""Поиск каналов по ключевым словам -> пополнение пула источников."""
from . import tgsess
if not tgsess.enabled():
print("сессия не настроена: data/tg.json или OMNI_TG_* в env")
return 1
queries = [q.strip() for q in str(a.queries).split(",") if q.strip()]
found = {}
for q in queries:
try:
rows = tgsess.search(q, limit=a.limit)
except Exception as e:
print(" %-28s ошибка %s" % (q, type(e).__name__))
continue
for r in rows:
if a.min_members and (r.get("participants") or 0) < a.min_members:
continue
prev = found.get(r["username"])
if prev:
prev["hits"] = prev.get("hits", 1) + 1
continue
r["hits"] = 1
found[r["username"]] = r
print(" %-28s каналов %d (всего уникальных %d)" % (q, len(rows), len(found)))
rows = sorted(found.values(), key=lambda x: (-(x.get("hits") or 0), -(x.get("participants") or 0)))
for r in rows[:20]:
print(" @%-28s %7s участн. hits=%d %s" % (r["username"], r.get("participants") or 0,
r["hits"], (r.get("title") or "")[:40]))
if not a.apply:
print("найдено %d каналов; добавь --apply чтобы дописать в пул" % len(rows))
return 0
import json
from pathlib import Path
p = Path(__file__).resolve().parents[1] / "data" / "radar_sources.json"
try:
d = json.loads(p.read_text(encoding="utf-8"))
except Exception:
d = {"domains": [], "channels": []}
chans = list(d.get("channels") or [])
have = {str(c).lstrip("@").lower() for c in chans}
added = 0
for r in rows:
u = str(r["username"]).lstrip("@")
if u.lower() in have:
continue
chans.append(u)
have.add(u.lower())
added += 1
d["channels"] = chans
p.write_text(json.dumps(d, ensure_ascii=False, indent=1), encoding="utf-8")
print("дописано каналов: %d | всего каналов в пуле: %d" % (added, len(chans)))
return 0