feat(bot): /tag и /типы — счётчики типов и топ по типу, доступны в read-only режиме; тест (20 passed)
This commit is contained in:
27
omni/bot.py
27
omni/bot.py
@@ -1,7 +1,7 @@
|
||||
"""Telegram-бот поверх парсера: лента, абузы, источники, прогон, автодобавление.
|
||||
|
||||
Запуск: OMNI_BOT_TOKEN=... python -m omni.bot
|
||||
Доступ: OMNI_BOT_OWNERS=<id>,<id> (пусто = read-only: /new /abuse /find /src /stats)
|
||||
Доступ: OMNI_BOT_OWNERS=<id>,<id> (пусто = read-only: /new /abuse /find /src /stats /tag)
|
||||
|
||||
Бот не постит никуда сам: только отвечает в личный чат тем, кто в списке.
|
||||
Команды:
|
||||
@@ -490,13 +490,34 @@ def pusher(every=300):
|
||||
print("pusher fail", e, flush=True)
|
||||
|
||||
|
||||
READONLY_CMDS = {"/start", "/help", "/new", "/abuse", "/find", "/src", "/stats"}
|
||||
READONLY_CMDS = {"/start", "/help", "/new", "/abuse", "/find", "/src", "/stats",
|
||||
"/tag", "/типы", "/sum", "/tr"}
|
||||
|
||||
|
||||
|
||||
def cmd_tag(chat_id, arg):
|
||||
"""Типы записей: /tag — счётчики, /tag leak — топ записей этого типа."""
|
||||
from . import taxonomy
|
||||
t = arg.strip().lower()
|
||||
if not t:
|
||||
counts = store.type_counts()
|
||||
rows = sorted(counts.items(), key=lambda x: -x[1])[:14]
|
||||
body = "\n".join("%-12s %d" % (taxonomy.LABELS.get(k, k), v) for k, v in rows)
|
||||
return _send(chat_id, "<b>типы записей</b>\n<pre>%s</pre>\n/tag <тип> — топ"
|
||||
% _esc(body), reply_markup=KB_MAIN)
|
||||
if t not in taxonomy.LABELS:
|
||||
return _send(chat_id, "нет такого типа: %s" % _esc(t), reply_markup=KB_MAIN)
|
||||
items, total = store.browse2(limit=8, sort="score", typ=t)
|
||||
if not items:
|
||||
return _send(chat_id, "по типу %s пусто" % _esc(t), reply_markup=KB_MAIN)
|
||||
head = "<b>%s</b> · всего %d\n\n" % (_esc(taxonomy.LABELS.get(t, t)), total)
|
||||
_send(chat_id, head + "\n\n".join(fmt_item(i) for i in items), reply_markup=KB_MAIN)
|
||||
|
||||
CMDS = {"/start": cmd_start, "/help": cmd_start, "/new": cmd_new, "/abuse": cmd_abuse,
|
||||
"/find": cmd_find, "/src": cmd_src, "/add": cmd_add, "/run": cmd_run,
|
||||
"/auto": cmd_auto, "/stats": cmd_stats,
|
||||
"/sub": cmd_sub, "/unsub": cmd_unsub, "/subs": cmd_subs,
|
||||
"/post": cmd_test, "/sum": cmd_sum, "/tr": cmd_tr}
|
||||
"/post": cmd_test, "/sum": cmd_sum, "/tr": cmd_tr, "/tag": cmd_tag, "/типы": cmd_tag}
|
||||
|
||||
|
||||
def handle(update):
|
||||
|
||||
@@ -170,3 +170,15 @@ def test_abuse_boost():
|
||||
a.title, b.title = "leak dump credentials 40M accounts", "weekly product update notes for teams"
|
||||
a.text = b.text = "x" * 600
|
||||
assert rank.score(a).score > rank.score(b).score
|
||||
|
||||
|
||||
|
||||
# ---------- 11. бот: /tag читается без владельца ----------
|
||||
def test_tag_command_readonly(monkeypatch):
|
||||
from omni import bot
|
||||
sent = []
|
||||
monkeypatch.setattr(bot, "OWNERS", set())
|
||||
monkeypatch.setattr(bot, "_send", lambda cid, text, **kw: sent.append(text))
|
||||
bot.handle({"message": {"chat": {"id": 1}, "from": {"id": 1}, "text": "/tag"}})
|
||||
assert sent and "типы записей" in sent[0], sent[:1]
|
||||
assert "/tag" in bot.CMDS
|
||||
|
||||
Reference in New Issue
Block a user