tg-сессия в комбайне + панель: ключи/сессия в шапке + фикс пустого radar_sources
- omni/config.py: tg_cfg() читает data/tg.json (вне git), env приоритетнее
- omni/tgsess.py: enabled()/fetch() подтягивают креды из config
- tools/tg_pick.py: перебор пула сессий, проверка is_user_authorized, личные аккаунты исключены
- omni claw pump: 2 канала -> 27 постов через сессию (проверено)
- omni/serve.py: /api/stats += keys{totals}, tg{enabled}
- web/index.html: строка статуса в шапке (ключей / сервисов / TG сессия)
- omni/cli.py radar --apply: пишет полный набор, а не только новые (повторный прогон обнулял файл)
- omni/cli.py radar --import-posts: --since-days + скип известных url до simhash
This commit is contained in:
110
tools/tg_pick.py
Normal file
110
tools/tg_pick.py
Normal file
@@ -0,0 +1,110 @@
|
||||
"""Выбрать рабочую Telegram-сессию и прописать её в data/tg.json (вне git).
|
||||
|
||||
Перебирает кандидатов из пула, проверяет is_user_authorized и права на чтение,
|
||||
берёт первую живую. Личные аккаунты (@reformboss, @R3fIex) исключены всегда.
|
||||
|
||||
Запуск:
|
||||
python tools/tg_pick.py # пул по умолчанию
|
||||
python tools/tg_pick.py --file my.json # свой список путей
|
||||
python tools/tg_pick.py --check # проверить, что уже прописано
|
||||
"""
|
||||
import argparse
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
OUT = ROOT / "data" / "tg.json"
|
||||
DEFAULT_POOL = Path("C:/Users/User/tmp/tg_chat_grow/alive_sessions.json")
|
||||
BANNED = {"reformboss", "r3flex", "r3fiex"}
|
||||
API_ID = "23926822"
|
||||
API_HASH = "f383e16e2f55bc0857291510fd513002"
|
||||
|
||||
|
||||
def candidates(pool_file):
|
||||
try:
|
||||
data = json.loads(Path(pool_file).read_text(encoding="utf-8"))
|
||||
except Exception:
|
||||
return []
|
||||
paths = data if isinstance(data, list) else list(data.values())
|
||||
out = []
|
||||
for p in paths:
|
||||
if not isinstance(p, str):
|
||||
continue
|
||||
low = Path(p).name.lower()
|
||||
if any(b in low for b in BANNED):
|
||||
continue
|
||||
stem = p[:-8] if p.lower().endswith(".session") else p
|
||||
if Path(stem + ".session").exists():
|
||||
out.append(stem)
|
||||
return out
|
||||
|
||||
|
||||
async def probe(stem, timeout=25):
|
||||
from telethon import TelegramClient
|
||||
|
||||
client = TelegramClient(stem, int(API_ID), API_HASH, connection_retries=1, timeout=12)
|
||||
try:
|
||||
await asyncio.wait_for(client.connect(), timeout)
|
||||
ok = await asyncio.wait_for(client.is_user_authorized(), timeout)
|
||||
if not ok:
|
||||
return None
|
||||
me = await asyncio.wait_for(client.get_me(), timeout)
|
||||
if not me or (me.id in (7448683285, 809951394)):
|
||||
return None
|
||||
dialogs = 0
|
||||
try:
|
||||
async for _ in client.iter_dialogs(limit=200):
|
||||
dialogs += 1
|
||||
except Exception:
|
||||
pass
|
||||
return {"stem": stem, "uid": me.id, "username": me.username or "",
|
||||
"phone": (me.phone or "")[:6] + "…", "dialogs": dialogs}
|
||||
except Exception:
|
||||
return None
|
||||
finally:
|
||||
try:
|
||||
await asyncio.wait_for(client.disconnect(), 8)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
async def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("-n", "--need", type=int, default=12, help="сколько кандидатов проверить")
|
||||
ap.add_argument("--file", default=str(DEFAULT_POOL))
|
||||
ap.add_argument("--check", action="store_true")
|
||||
a = ap.parse_args()
|
||||
|
||||
if a.check:
|
||||
if not OUT.exists():
|
||||
print("не прописано")
|
||||
return 1
|
||||
d = json.loads(OUT.read_text(encoding="utf-8"))
|
||||
print("прописано:", d.get("session"), "| limit", d.get("limit"))
|
||||
rec = await probe(d["session"]) if d.get("session") else None
|
||||
print("состояние:", "жива, uid %s, диалогов %s" % (rec["uid"], rec["dialogs"]) if rec else "не отвечает")
|
||||
return 0 if rec else 2
|
||||
|
||||
cands = candidates(a.file)[: a.need]
|
||||
print("кандидатов проверяю:", len(cands))
|
||||
for stem in cands:
|
||||
rec = await probe(stem)
|
||||
print(" %-58s %s" % (Path(stem).name[:58], ("uid %s, диалогов %s" % (rec["uid"], rec["dialogs"])) if rec else "нет"))
|
||||
if rec and rec["dialogs"] >= 3:
|
||||
OUT.parent.mkdir(parents=True, exist_ok=True)
|
||||
OUT.write_text(json.dumps({"session": stem, "api_id": API_ID, "api_hash": API_HASH,
|
||||
"limit": "100"}, ensure_ascii=False, indent=1), encoding="utf-8")
|
||||
print("\nзаписано в data/tg.json: uid %s (@%s), диалогов %s"
|
||||
% (rec["uid"], rec["username"] or "-", rec["dialogs"]))
|
||||
return 0
|
||||
print("\nживых не нашёл — подключи сессию вручную в data/tg.json")
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(asyncio.run(main()))
|
||||
Reference in New Issue
Block a user