48 KiB
Telegram-бот: кнопки, канал, формат
set OMNI_BOT_TOKEN=<токен BotFather> # .bot_token, в git не попадает
set OMNI_BOT_OWNERS=<твой numeric id> # кому отвечает, можно несколько через запятую
python -m omni.bot
Экран бота — инлайн-кнопки: Лента, Абузы, Источники, Цифры, теги Промо / Триалы / Сливы, Подписка: вкл/выкл, Формат: кратко/полно, Пост в канал.
Команды: /new [N], /abuse [тег], /find <слово>, /src <слово>, /run <категория>, /add <url>, /auto [N], /stats, /sub [@канал], /unsub [@канал], /subs, /post [@канал].
Постинг в канал. Добавь бота админом канала с правом публикации и отправь /sub @твойканал — бот каждые 5 минут проверяет новые абузы и публикует только те, что появились после подписки. /post @твойканал — опубликовать подборку сразу, /unsub @твойканал — остановить. Дальше можно подключить свой бот: код один, токен свой, база общая.
Формат текста. кратко — заголовок, источник, тег. полно — плюс ссылка на запись. Переключается кнопкой и хранится на чат/канал: канал можно держать в одном формате, личку — в другом.
Про ключи не публикуем. Тег keys отфильтрован на уровне бота (HIDE_TAGS в omni/bot.py): записи, у которых после фильтра не осталось тегов, не попадают ни в /abuse, ни в автопостинг.
omni-parse
Один парсер под любую тему: Reddit, форумы, поисковики, X/Twitter, карточки товаров и платные search-API — в одну SQLite-базу с FTS5, дедупом и рейтингом.
Ставится без ключей. Платные провайдеры включаются сами, если в окружении есть ключ.
Состояние на сейчас
- источников: 869 в 11 категориях (662 базовых + 207 из реестра абузов + 19 Telegram-каналов, дубли вырезаны), записей в базе: 9889 (421 с ценой, 120 прогонов), из них 3135 из реестра абузов и 2966 из Telegram (превью + своя сессия)
- типы записей: 14 — каждая запись размечена по смыслу: новость 3693 · софт 516 · уязвимость 402 · релиз 361 · модель 331 · вопрос 265 · цена 205 · гайд 194 · датасет 126 · слив 90 · триал 41 · промо 34 · вакансия 21 · перепродажа 10
- X/Twitter: 30 аккаунтов читаются без API-ключей через
api.fxtwitter.com(313 твитов в базе) - разделы панели:
Лента·Находки·Источники·Telegram·Отслеживание·Дайджест+Система(Обзор·История сборов·API-ключи); полоса чипов «тип», фильтр «только с ценой», сортировкаscore/fresh/price, экспорт CSV/JSON, тёмная и светлая темы - health-аудит: живой/мёртвый/непроверенный по каждому источнику, причина в примечании
- Telegram-бот на той же базе:
/new,/abuse,/find,/src,/run,/add,/auto,/sum,/tr,/stats - тесты:
tests/test_regress.py— 16 проверок на те же баги, что ловило ревью; CI:.github/workflows/ci.yml(py3.10/3.11/3.12) - автоаудит:
tools/selfcheck.pyобновляетREPORT.mdи гоняет тесты,tools/autocommit.shкоммитит и пушит в Gitea + GitHub
| категория | источников |
|---|---|
company |
135 |
community |
131 |
security |
99 |
papers |
72 |
forum |
57 |
models |
40 |
abuse |
40 |
company_cn |
34 |
release |
30 |
benchmark |
16 |
company_kr |
11 |
Панель
python -m omni serve --port 8077
# http://127.0.0.1:8077/#/abuse
Маршруты через hash: #/feed · #/abuse · #/sources · #/tg · #/watch · #/digest · #/overview · #/runs · #/keys, горячие клавиши 1..4, палитра Ctrl K, категории в URL (?cat=), кнопка «авто-добавление» ищет новые фиды на уже подключённых хостах и сохраняет только те, что реально отдали записи.
Скриншоты панели
Снято с живого инстанса (python -m omni serve --port 8077), база на момент съёмки: 46 423 записи · 3 815 источников · 6 746 находок. Пересъёмка одной командой: python tools/shots.py (нужен playwright, ждёт исчезновения скелетонов и только потом стреляет).
Лента
Фильтры по периоду, категории и сортировке, чипы типов, экспорт CSV/JSON, читалка по клику.
Находки
Промо, триалы, сливы и панели с бесплатными API: 6 746 находок, 5 182 уникальных — перепечатки одного поста из разных каналов схлопнуты по подписи, в карточке видно сколько копий склеено. Фильтр по тегам (ключи / промо / триалы / сливы / кредиты / инвайты / lifetime deal).
Бесплатные API-панели
Отдельная вкладка в «Находках»: new-api шлюзы, у которых открыт бесплатный доступ к моделям. 175 панелей в реестре, 90 с полностью бесплатными моделями (prompt и completion = 0), проверка идёт через публичный /api/pricing — учётные данные не запрашиваются.
Источники
Реестр на 3 815 источников: тумблер вкл/выкл, результат проверки, число записей в базе, дата последней проверки, добавление своего фида и health-аудит по категории.
Telegram
Своя серверная сессия: поиск каналов по теме через Telegram и импорт выбранных публикаций в базу (глубина — 100 постов на канал).
Отслеживание и Дайджест
Правила watchlist по слову и типу записи (совпадения считаются с момента добавления правила) и Markdown-сводка за сутки/3 дня/неделю с экспортом.
Система: обзор, история сборов, ключи
Счётчики реестра и импорта, журнал прогонов с числом новых/дублей/пустых по каждому источнику, состояние пула API-ключей по сервисам — только готовность и остывание, без значений и фрагментов ключей.
Что умеет
| Провайдер | Что тянет | Ключ |
|---|---|---|
reddit |
поиск по постам и комментариям через api.pullpush.io (архив Reddit) + публичный json как запас | нет |
forums |
Discourse (9 инстансов), Hacker News (Algolia), Lobsters, XenForo, веб-версии Telegram-каналов | нет |
ddg |
html-выдача DuckDuckGo | нет |
bing |
html-выдача Bing, ссылки раскодируются из ck/a?...u=a1<base64url> |
нет |
mojeek |
html Mojeek (свой индекс, без капчи) | нет |
x |
без платного API: oembed по URL твита, syndication-таймлайн профиля, поиск твитов через ddg/bing/mojeek | нет |
tavily |
Tavily search | TAVILY_API_KEY |
exa |
Exa search + текст страниц | EXA_API_KEY |
you |
You.com search | YOU_API_KEY |
firecrawl |
Firecrawl search | FIRECRAWL_API_KEY |
cards |
карточки товаров: JSON-LD Product/Offer, OpenGraph, microdata, цена/валюта/наличие | нет |
treg |
treg-поиск | TREG_TOKEN |
feed |
обход реестра из 450 лент/API без запроса (см. ниже) | нет |
python -m omni providers печатает, что реально поднялось в этом окружении.
Что было сломано и что стало (по ревью)
Отдельный заход по Telegram: адаптер tg_web тянул в базу Channel created,
Channel photo updated и посты из одной ссылки — 150 мусорных записей из 285.
После переписывания: 0 служебных, заголовки из тела поста
(СЛИВ: 1300+ АККАУНТОВ ДЛЯ ВАС! вместо 🛑); чистка старых — tools/purge_tg_junk.py --apply,
обновление заголовков без перезаписи базы — tools/fixtg.py.
Скор получил сигнал абуза (omni/rank.py, ABUSE_TERMS): утечки, CVE, эксплойты, комбо-листы,
сливы ключей и аккаунтов дают до +1.8 — топ базы теперь инциденты, а не релизы.
Пересчёт существующих записей — tools/rescore.py --apply.
Замеры сняты на этой машине, до и после правок. Скепсис к ревью тоже был: два пункта не подтвердились, они отмечены.
| пункт | было | стало |
|---|---|---|
/run в боте |
new += store.add(items) → TypeError, команда падала всегда |
n_new, _dup = store.add(items); прогон отдаёт готово: собрано 1, новых 1 |
| параметры API | ?limit=-1 → вся база (SQLite LIMIT -1), ?limit=abc → трейс и обрыв |
limit=-1 → 1 строка, abc → 40, 99999 → 200 (HTTP 200 во всех трёх) |
| соединения SQLite | with conn() коммитит без close(): 200 вызовов → +76 хендлов |
with db() (commit/rollback/close): 200 вызовов → +0 |
| троттлинг | 24 вызова на хост при 0.3с проходили за 0.9с вместо 6.9с | слот резервируется до сна, тест держит паузу и в 6 потоков |
| владелец бота | пустой OMNI_BOT_OWNERS → владельцем становился первый написавший |
без env бот в read-only: /new /abuse /find /src /stats, мутации отбиваются |
мёртвый abuse_sources.py |
237 строк, 0 импортов | подключён: +191 источник категории abuse (31 дубль отсеян по url) |
| дубли реестра | дубли по url | all_sources() дедуплицирует: 853 источника = 853 уникальных url |
JOBS в панели |
рос без границ, 500 запусков → 500 записей | eviction до 300 при переходе через 400 |
push_new |
уходили самые старые записи окна (fresh[-per_chat:]) |
уходят самые свежие (fresh[:per_chat]) |
ai.py |
sleep(1.5 + attempt) и после последней попытки |
спит только перед повтором |
Что из ревью не подтвердилось: rank.py не мёртвый — его зовёт cli.py в трёх местах; дублей в реестре был один, а не 38 (на старой базе ревью их было больше). except Exception осталось 59 на ~5000 строк: часть глушит сетевые парсеры осознанно, но в панели ни один запрос больше не отдаёт трейс — параметры валидируются до вызова.
Установка
pip install -r requirements.txt
cp .env.example .env # ключи по желанию, ни один не обязателен
Быстрый старт
# что доступно
python -m omni providers
# поиск по одной теме в четырёх бесплатных источниках
python -m omni search "scraping twitter without api" --providers reddit,forums,ddg,bing --limit 12 --show 10
# реестр источников: сколько и каких
python -m omni sources
python -m omni sources --category papers,security --list
# обход реестра БЕЗ запроса: 589 источников -> база
python -m omni feed --category community --limit 8
python -m omni feed --limit 15 # всё подряд
python -m omni feed --only arxiv_cs_ai,hn_top,reddit_localllama
# прогон по списку тем из themes.txt (по теме на строку)
python -m omni fanout --providers reddit,forums,ddg,bing --limit 10
# топ базы, статистика, поиск по своей базе
python -m omni top --limit 20
python -m omni stats
python -m omni find "proxy"
# карточки товаров по URL
python -m omni cards https://example.com/product
# выгрузка
python -m omni export --format jsonl --out data/dump.jsonl
Реестр источников
omni/sources.py + omni/sources_ext.py + omni/sources_auto.py — 1072 источника в 11 категориях, у каждого свой адаптер и флаг вкл/выкл. Из них 467 abuse (включая 61 авто-подключённый aa_) и 37 в активной авто-группе aa_ (остальные 24 авто-кандидата совпали по url с уже существующими источниками и были схлопнуты дедупом):
- papers 49 — arxiv по 25+ разделам (cs.AI/LG/CL/CV/RO/IR/CR/SE/NE/MA/DC/DB/HC/SD/CY, stat.ML, eess.AS/SP/IV, math.OC, q-bio.NC, cs.GR, cs.AR, cs.PF), HF daily papers, OpenAlex, Semantic Scholar, Papers with Code, Connected Papers
- company 95 — ленты OpenAI, Google AI/Research/DeepMind, Microsoft Research, NVIDIA, Apple ML, Amazon Science, HF, Meta AI, Mistral, Cohere, Together, Perplexity, Groq, Cerebras, Stability, Databricks, Anyscale, Modal, W&B, LangChain, LlamaIndex, vLLM, Replicate, Fireworks, SambaNova, Scale, xAI, Salesforce, AWS ML, Azure AI, Anthropic, AI2, EleutherAI, LAION, Runway, ElevenLabs, Deepgram, AssemblyAI, Pinecone, Weaviate, Qdrant, Chroma, Unsloth, Axolotl
- company_cn 31 — Qwen, DeepSeek changelog, Moonshot, Zhipu, Baichuan, MiniMax, StepFun, 01.AI, InternLM, ChatGLM + GitHub-орги Tencent-Hunyuan, PaddlePaddle, bytedance, mindspore-ai, QwenLM, deepseek-ai, MoonshotAI, THUDM, OpenBMB, Shanghai-AI-Lab
- company_kr 10 — Kakao tech, Naver Cloud/D2, Samsung Research, LG AI Research, Upstage, Rebellions, Twelve Labs, FriendliAI
- community 49 — HN top/new/ask/show, Lobsters (4 тега), GeekNews, Reddit: LocalLLaMA, OpenAI, singularity, MachineLearning, deeplearning, netsec, programming, rust, golang, Python, webdev, selfhosted, devops, datascience, androiddev, javascript, linux, experienced_devs
- security 45 — THN, BleepingComputer, Krebs, SANS ISC, Packet Storm, CISA advisories + CISA KEV (JSON), NVD CVE (JSON), Exploit-DB, Project Zero, PortSwigger, GitHub Security, Rapid7, Qualys, Tenable, CrowdStrike, SentinelOne, Unit42, Talos, Securelist, WeLiveSecurity, Malwarebytes, Schneier, Graham Cluley, HackerOne hacktivity, Bugcrowd, Intigriti, YesWeHack, CTFtime, OWASP, SANS diaries, Risky Business, tl;dr sec, Detection Engineering
- forum 31 — 10 Discourse-инстансов (discuss.python, community.openai, forum.cursor, discuss.huggingface, forum.obsidian, community.cloudflare, discuss.elastic, forum.gitlab, community.home-assistant, discuss.grafana), XenForo BHW, веб-версии Telegram-каналов (durov, telegram, AI-каналы), Stack Overflow tags, Reddit-миграции
- models 18 — HF trending/new (модели, спейсы, датасеты), HF по 6 пайплайн-тегам, Ollama library + search, LM Studio catalog, OpenRouter models + pricing (JSON), Civitai, Replicate explore
- benchmark 10 — Open LLM Leaderboard, LMArena, Artificial Analysis, Epoch AI, SWE-bench, LiveBench, HELM, MTEB, BigCodeBench, Chatbot Arena
Адаптеры: rss, generic_json, or_models, cisa_kev, nvd, json (HF, HN, OpenAlex, S2, Discourse), html (список + детальная), github_org. Медленные хосты (reddit, github, HF, arxiv, openrouter) обходятся последовательно с паузой, остальные — в 8 потоков. Для arxiv RSS, который часто отдаёт пустое, есть fallback на официальный API (export.arxiv.org/api/query).
Авто-расширение источников (публичные API без ключей)
omni/sources_auto.py генерируется tools/auto_expand.py — руками не править, правки перезапишутся. Пул кандидатов лежит в data/source_candidates.json, здоровье — в data/source_health.json.
python tools/auto_expand.py --probe # проверить всех: имя | LIVE/DEAD | items | заголовки
python tools/auto_expand.py --write # probe + пересобрать omni/sources_auto.py (живые, items>0)
python tools/auto_expand.py --write-only # пересобрать из последнего health (без сети)
python tools/auto_expand.py --discover # добрать бесплатные (Auth=No) эндпоинты из public-apis
python tools/auto_expand.py --add NAME URL --adapter rss # новый кандидат одной строкой
python tools/auto_cycle.py # полный цикл: probe → write → feed → индекс → коммит/пуш
Правила: кандидат попадает в реестр только если адаптер реально вернул items > 0; после 3 прогонов подряд с нулём источник выкидывается из генерации автоматически. Группы в сгенерированном файле: json, reddit, social, discourse, rss, tg.
Универсальный generic_json понимает описание в extra: rows (путь к списку через точку), title_key, url_key, text_key, date_key, base + slug_key (собрать ссылку из слага), deref (спуститься в подобъект). Поэтому большинство новых JSON-источников — одна строка в data/source_candidates.json, без нового кода. Отдельные адаптеры только там, где схема нестандартная: bsky_search (Bluesky public API, без токена), mastodon_tag, tg_web (t.me/s/<channel>), discourse (latest.json).
Подключено в этом апдейте (61 живой из 81 проверенного; отбор aa_ = 37 источников после дедупа по url, пусто 0/37 | собрано 673, новых 234):
- JSON без ключа — dev.to, Lobsters, npm search (llm / mcp / free api keys), crates.io, Docker Hub, Stack Overflow (openai / prompt-injection), GitLab (new/llm), Hugging Face spaces + models trending
- Reddit — через
api.pullpush.io(архив Reddit, без OAuth): LocalLLaMA, FreeAI, OpenAIAPI, ChatGPT, selfhosted - Bluesky —
public.api.bsky.appsearchPosts: free tokens api, openrouter, free api, ai keys, llm api - Mastodon — теги ai / openai / llm
- Discourse — community.openai, discuss.huggingface, forum.cursor, discuss.python, discuss.fly, forum.obsidian
- RSS — Habr, The Decoder, MarkTechPost, OpenAI news, Simon Willison, HF blog, TechCrunch AI, 52pojie, Latent Space, Interconnects, Import AI, TLDR AI, smol.ai, Snyk, JFrog, Wiz, UpGuard, SecurityWeek, Cloudflare, Bleeping, The Hacker News
- Проверка живости —
tools/auto_expand.py --probe(items>0 обязателен), здоровье вdata/source_health.json, три нуля подряд → кандидат выкидывается из генерации - Telegram-превью — ai_newz, data_secrets, neurohive, gpt4telegram, dataleak, denissexy
--only в omni feed понимает префикс: python -m omni feed --only aa_ берёт всю авто-группу. Для github_search поднимается лимит, если в .env есть GITHUB_TOKEN (анонимно 10 запросов/мин, с токеном 30).
Крон (каждые 6 часов, tools/auto_cycle.py): проверка кандидатов → пересборка sources_auto.py → докачка только при изменениях → пересборка abuse-индекса → коммит auto: источники N live и пуш в gitea/github. Лог — data/auto_cycle.log.
Отбор из public-apis (--discover) фильтруется по категориям (AI / ML / Security / News / Open Data / Development / Text Analysis / Cryptocurrency) и чёрному списку мусора (waifu/anime/cat facts/insurance/…): из 40 «бесплатных» эндпоинтов публичного каталога реально отдают данные единицы, остальное — витрины без API. Поэтому основной прирост идёт не из каталогов, а из конкретных известных эндпоинтов (--add).
Условный GET (ETag/Last-Modified) — в omni/net.py: ответ с ETag/Last-Modified кладётся в data/http_cache/, повторный запрос уходит с If-None-Match/If-Modified-Since, 304 отдаётся из кэша. Замер на huggingface.co/blog/feed.xml: 1.73 с → 0.74 с при идентичном теле (262 549 байт). Прогон по 60+ RSS/HTML-источникам ускоряется без потери свежести — новые записи приходят, как только меняется сам документ.
Новые правила абуз-разбора (omni/abuse.py): форматы ключей sk-ws-*, ek_live_*, abl_*, xpl_*, AIza*, ak_*, sk-or-v1-*; теги farm (авторег, фермы, пул прокси, ротация ip) и weights (abliterated/uncensored/GGUF); в tool добавлены new-api/one-api/sub2api/chat2api/gpt-load/shim/openai-compatible/reverse proxy; в credits — «$N free credits». Проверка классификатора: панель new-api → 202 (trial/tool/credits/freeapi/infra), авторег-ферма → 96 (tool/resale/farm/infra), «погода» → 0.
Панель и команды
python -m omni serve --port 8077 # веб-панель + JSON API (без сборки, без npm)
python -m omni feed --limit 10 # обход всего реестра
python -m omni doctor --fix # проверить источники и подобрать рабочие фиды
python -m omni digest --out data/digest.md
Панель — две вкладки:
- лента — счётчики (записей, с ценой, прогонов, источников, включённых), поиск по базе, фильтр по категориям, кнопка «собрать ленту» с прогрессом и разбивкой fetched/new/dup/empty.
- источники — менеджер реестра:
- таблица всех 589 источников: переключатель вкл/выкл, категория, тип, url, статус (жив / мёртв / не проверен), число записей;
- фильтр по имени/url и по категории;
- подключить источник — форма (имя, url, категория): тип и адаптер определяются по url автоматически (
/rss→ rss,.json//api/→ generic_json,github.com/org→ github_org,t.me/s/→ tg_web), запись живёт в SQLite и сразу участвует в обходах; - проверить всё / проверить категорию — фоновой джоб: реальный фетч каждого источника, запись
status/items/note/checked, прогрессdone/total, живых/мёртвых; - вкл все / выкл все — массово по текущему фильтру;
- удаление своих источников (реестровые только выключаются).
Выключенный источник не дёргается ни панелью, ни omni feed, ни omni doctor — фильтр применяется в sources.pick().
API: GET /api/stats, GET /api/items?category=&q=&limit=&offset=, GET /api/sources?category=&q=,
POST /api/sources/toggle {name,enabled}, POST /api/sources/add {name,category,url},
POST /api/sources/remove {name}, POST /api/sources/check {name|names|category|all},
POST /api/feed {category,limit}, GET /api/job/<id>.
Состояние источников — таблицы source_flags и source_custom в той же SQLite (data/omni.sqlite3).
Типы записей (не путать с категорией источника)
Категория отвечает «откуда», тип — «что именно». Одна запись получает до 3 типов, они лежат в items.types и отдаются в API (/api/types, ?type=leak), видны бейджами в панели, попадают в CSV.
слив · триал · софт · промо · перепродажа · уязвимость · релиз · гайд · датасет · модель · вакансия · цена · вопрос · новость
Правила лежат в omni/taxonomy.py: взвешенные RU/EN-паттерны, порог по весу, чтобы «free» в рекламе не превращалось в «триал».
Telegram-каналы: реальные абузы без сессии
Публичное веб-превью t.me/s/<канал> — ни Telethon, ни api_id, ни токена бота.
Адаптер tg_web берёт div.tgme_widget_message_text, режет служебное
(Channel created, Channel photo updated, pinned), пустыши и посты из одной ссылки,
заголовок собирает из первой содержательной строки, дату — из time[datetime], просмотры — из
tgme_widget_message_views. Для каналов с тегом leak порог ниже: они пишут коротко
(«<домен> 2M users»), и раньше такие посты отбрасывались как мусор.
Проверка каналов — python tools/tg_discover.py --file data/tg_cand.txt --min 2:
печатает по каждому статус, сколько постов даёт парсер и сколько из них новые.
Из 87 проверенных каналов живых 19; выкинуты те, у кого превью пустое
(leakbase, abuse_ch, cracked_io, ai_zona, gpt_bot_news, codeby — только
Channel created и инвайт-ссылки).
Живые: thehackernews, bleepingcomputer, cvefeed, vulnwatch, ransomware_news,
breachradar, poc_in_github, hunt_news, vxunderground, true_secator, infosec_ru,
xakep_ru, prompt_injection, ai_newz, neurohive, neuralshit, seeallochnaya,
ai_free_ru, ai_products, addmetana, alstack.
Один прогон этих каналов: 324 поста, 0 пустых источников.
Своя сессия: глубина вместо 20 постов
Веб-превью отдаёт ~20 последних постов. Свой аккаунт (Telethon) по тем же каналам
берёт 200: прогон 20 каналов дал 2832 поста, 2592 новых записи (остальное дубли).
Каналы с выключенным превью тоже читаются, но пустые не оживают: у leakbase
и через сессию 4 поста — только инвайты.
Секретов в репозитории нет, всё через окружение:
export OMNI_TG_SESSION=/path/to/account # .session без расширения
export OMNI_TG_API_ID=... OMNI_TG_API_HASH=...
python -m omni pump thehackernews,cvefeed --limit 200 --apply
Без env команда честно говорит, что сессии нет, и парсер продолжает работать
на веб-превью. Аудит пула сессий — tg_alive_audit.py: из 856 файлов живыми
оказались 121 (остальные unauthorized/битые), их и берём.
Ещё по ходу: у CVE-каналов тело advisory без идентификатора в заголовке —
теперь CVE-2026-97254 · Improper Neutralization..., таких заголовков 471.
X / Twitter без ключей
omni/providers/x.py→profile(handle)тянет ленту черезapi.fxtwitter.com/2/profile/<handle>/statuses: полный текст, метрики (лайки, репосты, просмотры), дата, язык.- адаптер
x_userвomni/feeds.py, источники —omni/sources_x.py(30 живых хендлов: abuse/security/models/community). - путь
syndication.twitter.com(429 для всех IP, включая VPS и прокси) и nitter-зеркала (410/403/0) выпилены — не тратить время. - свой хендл добавляется как источник:
{"name": "x_ник", "category": "abuse", "kind": "tweet", "url": "https://x.com/ник", "adapter": "x_user", "extra": {"handle": "ник"}}.
Ключи парсеров: один пул на весь комбайн
Ключи не лежат в коде и не уходят в git — только локально и в env.
python tools/build_vault.py— собирает пул изMASTER_KEYS.csvи локальных дампов вdata/vault.json(файл в.gitignore, значения никогда не печатаются).python -m omni keys/python -m omni keys --service firecrawl -v— сводка: сервис, сколько ключей, сколько готовых, маски.python tools/vault_check.py— живая проверка: помечаетlive / dead / rate / nofund.- Рантайм
omni/vault.py: сначала env (FIRECRAWL_API_KEY,TAVILY_API_KEY, …), потом пул; ротация по кругу; остывание ключа после 401/402/403 — час, после 429 — 10 минут. Один мёртвый ключ не ломает прогон. - Провайдеры поиска/скрейпа (
firecrawl,tavily,exa,serper,jina,apify) берут ключ из пула автоматически — отдельная настройка не нужна. - Панель:
GET /api/keys— сводка по сервисам без значений, строка «N ключей · M сервисов» в сайдбаре. - В пуле сейчас 66 сервисов и ~9.9k записей; из парсерных:
firecrawl70 (живые, поиск проверен),2captcha36,anticaptcha15,capsolver1,telegram77 ботов; ключиopenai/deepseek/openrouterидут на перевод и саммари. - Капча для закрытых площадок:
2captcha/anticaptcha/capsolverиз того же пула.
abuse-radar внутрь реестра
Радар (домены + каналы + посты) больше не отдельная система:
python -m omni radar— dry-run: сколько доменов с каким score и сколько живых каналов.python -m omni radar --apply --min-score 20— пишетdata/radar_sources.json: домены становятся HTML-источниками, каналы — Telegram-источниками (tg_web).python -m omni radar --import-posts— заливает посты каналов радара в общую базу как обычные записи (типы, score, фильтры, бот работают сразу).- Источники радара помечены
opt_in: в обычном обходе их нет, чтобы 2.5k новых источников не тормозили ленту. Берутся явно:omni feed --tags radarили--category abuse. - Дефолтный путь к базе радара:
C:/Users/User/tmp/abuse_radar/radar_server.db, переопределяется--db.
Китайские и дарк-форумы
python tools/wave_cn.py [--apply]— проверяет живые китайские/азиатские площадки и генерируетomni/sources_cn.py. Живых 9: 52pojie, nodeseek, kanxue, anquanke, 4hou, xz.aliyun, ithome, cnbeta, v2ex.omni/sources_dark.py— дарк/крэк-форумы, реально отдающие темы без логина:cracked.st,nulledbb.com,forum.tuts4you.com,leak.sx(плюс существующий наборab_*).- Для площадок под JS-челленджем:
python tools/cf_cookies.py [host …]— открывает сайт настоящим браузером (Camoufox), ждёт прохода проверки, снимает cookies вdata/cookies.json(вне git), после чегоomni/net.pyподставляет их сам. Проверка:python tools/cf_cookies.py --check. net.get(..., proxy=…)— принудительный прокси для отдельного источника (например CF-форумы через чистый DE-выход).- Честное ограничение:
xss.is,exploit.in(форум),blackhatworld,hackforumsотдают контент только аккаунту — cookie-прохода мало, нужен логин.
Автоаудит и непрерывные коммиты
python tools/selfcheck.py— компиляция пакета, счётчики базы, распределение типов, топ источников, поиск дублей и пустых источников; пишет блок вREPORT.mdи историю вdata/selfcheck.jsonl.bash tools/autocommit.sh [--feed]— самоаудит (+ подкачка, если--feed), коммит только при реальных изменениях, пуш в оба ремоута.- cron: каждые 6 часов аудит-коммит, каждые 12 часов аудит + подкачка источников.
omni dedupe [--apply]— схлопывает дубли по url (или source+title при пустом url), вставка тоже дедуплицирует по url.
Как устроено
omni/net.py— лестница транспорта: httpx → curl_cffi (подмена TLS-фингерпринта) → прокси из env. Троттлинг по хосту, лимит байт, пометка блокировок.omni/model.py— единая схема записи: провайдер, тип, url, заголовок, текст, автор, дата, теги, цена, счёт, simhash.omni/filter.py— релевантность: запрос должен быть покрыт текстом (≥60% терминов) и хотя бы один термин — в заголовке. Для русского сравнивает по 5-символьному префиксу, иначе морфология убивает совпадения.omni/store.py— SQLite WAL + FTS5, таблицыitems,bands,runs. Дедуп: simhash по шинглам, сравнение по Хэммингу ≤3 по бакетам.omni/rank.py— вес провайдера, свежесть, наличие цены, вовлечение.omni/providers/— по файлу на семейство источников, реестр в__init__.py.
Реальные прогоны
python -m omni search "scraping twitter without api" --providers reddit,forums,ddg,bing
bing 10 ok | ddg 10 ok | forums 10 ok | reddit 8 ok
собрано 38, новых 31, дублей 7
python -m omni fanout # 8 тем из themes.txt
итого новых 200, дублей 5
python -m omni stats
записей 266 | прогонов 56 (ok 37)
ddg=93 bing=85 forums=56 reddit=32
Ограничения
- Reddit напрямую с серверных IP отдаёт 403 — используется архив pullpush; свежие посты (последние часы) в архиве могут отсутствовать.
- X/Twitter без токена: доступны только публичные встраивания и таймлайн профиля, полноценного полнотекстового поиска нет.
- mojeek отдаёт пустую страницу при агрессивном троттлинге — провайдер помечается, остальные работают.
cardsне обходит защиту от парсинга: если страница рендерится JS, разметки в html не будет.
Лицензия
MIT.
Абузы, авто-добавление и Telegram-бот
- абузы: категория
abuse— 31 живая площадка (XenForo/Discourse/Telegram/RSS), включая свои каналы, классификаторomni/abuse.pyраскладывает записи по тегамключи / промо / триалы / сливы / софт / продажа / новости. В панели — отдельный раздел#/abuse, в боте —/abuse [тег]. - авто-добавление:
omni/discover.pyищет фиды на уже подключённых хостах и каталогах, проверяет их теми же адаптерами и сохраняет только те, что реально отдали записи. В панели — кнопка «авто-добавление», в API —POST /api/discover?hosts=40&add=25. - новости: любые RSS/Atom/JSON-ленты (редакции, релизы, сообщества) подключаются как обычный источник или через
/add <url>в боте — отдельной схемы не требуется.
Telegram-бот
set OMNI_BOT_TOKEN=<токен BotFather>
set OMNI_BOT_ALLOW=<твой numeric id>
python -m omni.bot
Команды: /new [N], /abuse [тег], /find <слово>, /src <слово>, /run <категория>, /add <url>, /stats. Бот работает на той же базе и том же реестре, что панель; отвечает только id из OMNI_BOT_ALLOW.
ИИ: перевод и саммари
Абузные площадки в основном не на русском: nodeloc (китайский), afflift и BHW (английский). Лента переводится на лету, подборка сворачивается в саммари — 3-5 пунктов, что раздают, платно или халява, где.
Подключение. Любой OpenAI-совместимый эндпоинт:
set OMNI_AI_KEY=<ключ> # обязателен только для ИИ-функций
set OMNI_AI_BASE=https://api.reformboss.com/v1
set OMNI_AI_MODEL=gpt-6.1-sol # по умолчанию он же
Если OMNI_AI_KEY не задан, omni/ai.py ищет ключ в конфиге Hermes (custom_providers с reformboss в base_url). Без ключа парсер работает как раньше: ИИ-функции молча выключаются, кнопки пишут «ИИ не подключён».
В боте: кнопки ИИ-саммари, Перевод: вкл/выкл, Саммари в подписке: вкл/выкл; команды /sum [тег], /tr <id|слово>. Перевод включается на чат/канал: в канале можно держать русский формат, в личке — оригинал.
Автопостинг. Если для канала включено «саммари в подписке», бот перед списком новых абузов пишет ИИ-сводку, дальше 5 находок с переводом заголовков.
В панели: вкладка Абузы → кнопка ИИ-саммари (GET /api/summary?tag=promo&limit=14).
Как это сделано: omni/ai.py, только stdlib (urllib), ретраи с падением на glm-5.3 и qwen3.8-flash, если основная модель отдала 503/429. Переводы и саммари кэшируются в таблице ai_cache по хешу текста — повторные прогоны не тратят токены. Ключи не пишутся в репозиторий и не логируются.
Что нужно подключить
- Python 3.11+ и зависимости:
pip install -r requirements.txt(httpx, curl_cffi, bs4, lxml). Больше ничего не обязательно — база создаётся сама вdata/omni.sqlite3. - Ни одного ключа не нужно. Reddit (архив), форумы (Discourse/XenForo/веб-Telegram), HN, arXiv, GitHub, HF, поисковики работают без регистрации. Платные search-API (
TAVILY_API_KEY,EXA_API_KEY,YOU_API_KEY,FIRECRAWL_API_KEY) подхватываются из env, если они есть: с ними больше покрытие, без них проект полностью рабочий. - Свои источники:
python -m omni add <url> --category forum --tags мои, кнопка «авто-добавление» в панели,POST /api/discoverили/autoв боте. Адрес проверяется живым запросом и сохраняется только если реально отдал записи (проверено:omni add https://lobste.rs/rss→добавлен manual_lobste_rs · rss · 6 записей). - Свои ключи, прокси и куки — всё через env или
config.jsonрядом с проектом:
{"proxy_mode": "list",
"proxies": ["http://user:pass@host:port"],
"cookies": {"site.com": "session=abc; csrf=xyz"}}
- ключи:
TAVILY_API_KEY,EXA_API_KEY,YOU_API_KEY,FIRECRAWL_API_KEY,JINA_API_KEY,SERPER_API_KEY,BRAVE_API_KEY,X_BEARER,REDDIT_CLIENT_ID+REDDIT_SECRET,TREG_TOKEN,GITHUB_TOKEN— подхватываются из.env/env,omni providersпоказывает, что подключилось; - прокси:
proxy_mode=off|list|env(OMNI_PROXIES=http://p1,http://p2) — используется третьим шагом лестницы, когда прямой запрос упёрся в блок (проверено: прямой egress 178.150.68.140 → через прокси 150.241.69.145); - куки:
cookiesвconfig.jsonилиOMNI_COOKIES='{"site.com":"a=b"}'— подставляются по хосту с матчем по суффиксу (проверено на echo-эндпоинте: обе куки дошли); - свой сервер:
python -m omni serve --port 8077поднимает панель и JSON API, за nginx/Caddy это уже удалённый инстанс на своей машине, база едет вOMNI_DB.
- Свой бот: токен BotFather в
OMNI_BOT_TOKEN, свой numeric id вOMNI_BOT_OWNERS, бота админом канала и/sub @канал.
Проект обновляется
Проект живой: реестр источников, адаптеры и классификатор абузов правятся по мере того, как площадки ломают разметку. Обновление:
git pull
pip install -r requirements.txt
python -m omni serve --port 8077 # панель
python -m omni.bot # бот, если нужен
База в data/ не перезаписывается — источники, здоровье и подписки остаются на месте. Ближайшие шаги: отдельная новостная лента с группировкой по сюжетам, скоринг абузов по свежести и частоте площадки, экспорт подборки в канал по расписанию.









