import re cats = open("data/_cats.md", encoding="utf-8").read().strip() types = open("data/_types.md", encoding="utf-8").read().strip() p = "README.md" s = open(p, encoding="utf-8").read() state_new = f"""## Состояние на сейчас - **источников: 665** в 11 категориях, **записей в базе: 5594** (224 с ценой, 120 прогонов) - **типы записей: 14** — каждая запись размечена по смыслу: {types} - **X/Twitter: 30 аккаунтов** читаются без API-ключей через `api.fxtwitter.com` (313 твитов в базе) - вкладки панели: `Лента` · `Источники` · `Прогоны` · `Абузы`; полоса чипов «тип», фильтр «только с ценой», сортировка `score/fresh/price`, экспорт CSV - health-аудит: живой/мёртвый/непроверенный по каждому источнику, причина в примечании - Telegram-бот на той же базе: `/new`, `/abuse`, `/find`, `/src`, `/run`, `/add`, `/auto`, `/sum`, `/tr`, `/stats` - автоаудит: `tools/selfcheck.py` обновляет `REPORT.md`, `tools/autocommit.sh` коммитит и пушит в Gitea + GitHub | категория | источников | |---|---| {cats}""" start = s.index("## Состояние на сейчас") end = s.index("## Панель") s = s[:start] + state_new + "\n\n" + s[end:] extra = """ ## Типы записей (не путать с категорией источника) Категория отвечает «откуда», тип — «что именно». Одна запись получает до 3 типов, они лежат в `items.types` и отдаются в API (`/api/types`, `?type=leak`), видны бейджами в панели, попадают в CSV. `слив` · `триал` · `софт` · `промо` · `перепродажа` · `уязвимость` · `релиз` · `гайд` · `датасет` · `модель` · `вакансия` · `цена` · `вопрос` · `новость` Правила лежат в `omni/taxonomy.py`: взвешенные RU/EN-паттерны, порог по весу, чтобы «free» в рекламе не превращалось в «триал». ## X / Twitter без ключей - `omni/providers/x.py` → `profile(handle)` тянет ленту через `api.fxtwitter.com/2/profile//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": "ник"}}`. ## Автоаудит и непрерывные коммиты - `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. """ anchor = "## Как устроено" s = s.replace(anchor, extra + anchor, 1) open(p, "w", encoding="utf-8", newline="\n").write(s) print("README updated", len(s))