### Telegram-бот: кнопки, канал, формат ```bash 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 `, `/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, дедупом и рейтингом. Ставится без ключей. Платные провайдеры включаются сами, если в окружении есть ключ. ## Состояние на сейчас - **источников: 589** в 11 категориях, **записей в базе: 3411** - вкладки панели: `Лента` · `Источники` · `Прогоны` · `Абузы` - health-аудит: живой/мёртвый/непроверенный по каждому источнику, причина в примечании - Telegram-бот на той же базе: `/new`, `/abuse`, `/find`, `/src`, `/run`, `/add`, `/auto`, `/stats` | категория | источников | |---|---| | `community` | 123 | | `company` | 119 | | `security` | 72 | | `papers` | 68 | | `forum` | 50 | | `models` | 35 | | `company_cn` | 34 | | `abuse` | 31 | | `release` | 30 | | `benchmark` | 16 | | `company_kr` | 11 | ## Панель ```bash python -m omni serve --port 8077 # http://127.0.0.1:8077/?view=abuse ``` `?view=feed|src|runs|abuse`, горячие клавиши `1..4`, палитра `Ctrl K`, категории в URL (`?cat=`), кнопка «авто-добавление» ищет новые фиды на уже подключённых хостах и сохраняет только те, что реально отдали записи. ## Что умеет | Провайдер | Что тянет | Ключ | |---|---|---| | `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` | нет | | `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` печатает, что реально поднялось в этом окружении. ## Установка ```bash pip install -r requirements.txt cp .env.example .env # ключи по желанию, ни один не обязателен ``` ## Быстрый старт ```bash # что доступно 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` — **589 источников в 9 категориях**, у каждого свой адаптер и флаг вкл/выкл: - **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`). ## Панель и команды ``` 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 ``` Панель — две вкладки: 1. **лента** — счётчики (записей, с ценой, прогонов, источников, включённых), поиск по базе, фильтр по категориям, кнопка «собрать ленту» с прогрессом и разбивкой fetched/new/dup/empty. 2. **источники** — менеджер реестра: - таблица всех 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/`. Состояние источников — таблицы `source_flags` и `source_custom` в той же SQLite (`data/omni.sqlite3`). ## Как устроено - `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` раскладывает записи по тегам `ключи / промо / триалы / сливы / софт / продажа / новости`. В панели — отдельная вкладка (`?view=abuse`), в боте — `/abuse [тег]`. - **авто-добавление**: `omni/discover.py` ищет фиды на уже подключённых хостах и каталогах, проверяет их теми же адаптерами и сохраняет только те, что реально отдали записи. В панели — кнопка «авто-добавление», в API — `POST /api/discover?hosts=40&add=25`. - **новости**: любые RSS/Atom/JSON-ленты (редакции, релизы, сообщества) подключаются как обычный источник или через `/add ` в боте — отдельной схемы не требуется. ### Telegram-бот ```bash set OMNI_BOT_TOKEN=<токен BotFather> set OMNI_BOT_ALLOW=<твой numeric id> python -m omni.bot ``` Команды: `/new [N]`, `/abuse [тег]`, `/find <слово>`, `/src <слово>`, `/run <категория>`, `/add `, `/stats`. Бот работает на той же базе и том же реестре, что панель; отвечает только id из `OMNI_BOT_ALLOW`. ## Что нужно подключить 1. **Python 3.11+** и зависимости: `pip install -r requirements.txt` (httpx, curl_cffi, bs4, lxml). Больше ничего не обязательно — база создаётся сама в `data/omni.sqlite3`. 2. **Ни одного ключа не нужно.** Reddit (архив), форумы (Discourse/XenForo/веб-Telegram), HN, arXiv, GitHub, HF, поисковики работают без регистрации. Платные search-API (`TAVILY_API_KEY`, `EXA_API_KEY`, `YOU_API_KEY`, `FIRECRAWL_API_KEY`) подхватываются из env, если они есть: с ними больше покрытие, без них проект полностью рабочий. 3. **Свои источники**: кнопка «авто-добавление» в панели, `POST /api/discover`, `/auto` в боте или `python -m omni add ` — адрес проверяется реальным запросом и сохраняется только если отдал записи. 4. **Свой бот**: токен BotFather в `OMNI_BOT_TOKEN`, свой numeric id в `OMNI_BOT_OWNERS`, бота админом канала и `/sub @канал`. ## Проект обновляется Проект живой: реестр источников, адаптеры и классификатор абузов правятся по мере того, как площадки ломают разметку. Обновление: ```bash git pull pip install -r requirements.txt python -m omni serve --port 8077 # панель python -m omni.bot # бот, если нужен ``` База в `data/` не перезаписывается — источники, здоровье и подписки остаются на месте. Ближайшие шаги: отдельная новостная лента с группировкой по сюжетам, скоринг абузов по свежести и частоте площадки, экспорт подборки в канал по расписанию.