feat(crawler): rss-crawler + очередь кандидатов + воркер (фазы 1-3); веб-статус /crawlers; openspec rss-crawler, tg-crawler-publisher-prototype

This commit is contained in:
kpa39l
2026-09-22 17:39:09 +00:00
parent 56610fa836
commit a10ab9fa3c
6 changed files with 327 additions and 1 deletions
+7
View File
@@ -1,6 +1,7 @@
# AGENT.MD — Правила проекта VESTI
## Правило №1: ВСЕ изменения — через OpenSpec
- **Перед каждым планируемым изменением — обязательно grill-with-docs** (интервью по дизайн-дереву: глоссарий в CONTEXT.md + ADR при необходимости). Только после достижения общего понимания с пользователем — создавать change.
- **Любое изменение проекта (багфикс, фича, рефакторинг, конфиг, деплой, docs) оформляется как отдельный change** в `/opt/vesti/openspec/changes/<change-name>/`.
- **НЕ начинать правки кода/файлов, пока change не создан и не провалидирован (`openspec validate` чисто).** Это обязательное требование (у VESTI нет бэкапа — OpenSpec фиксирует состояние и откат).
- **Сразу после правок — обновить STATUS.md/TODO.md и сделать бэкап** (см. «Бэкап» ниже).
@@ -16,6 +17,7 @@
## Стек и архитектура
- Новостной агрегатор: TG-краулер → классификатор (Ollama qwen3:8b-nothink) → веб-модерация → публикация в Telegram.
- Веб: :8400 — страницы /candidates (модерация), /crawlers (статус краулеров, запуск воркера), /sources (управление источниками: add/edit/toggle-pause/delete; источник истины — sources.yaml).
- `vesti-web` (FastAPI+Jinja2, :8400, systemd-юнит) --HTTP POST--> `publisher-service` (FastAPI, Docker-контейнер, :8410) --Bot API (SOCKS5 127.0.0.1:1080)--> Telegram @dedinit_vesti.
- БД: SQLite `/opt/vesti/db/vesti.db` — открывать с WAL + busy_timeout (иначе `database is locked` при фоновом классификаторе).
- Фронтенд: **без внешних CDN** (никаких unpkg/jsdelivr). Bootstrap локален: `web/static/bootstrap.min.css`, htmx запрещён. approve/reject — обычные POST-формы.
@@ -43,6 +45,11 @@ sudo systemctl restart vesti-web # веб :8400 (0.0.0.0, uvicorn web.a
docker compose -f services/publisher/docker-compose.yml up -d --build # publisher :8410
curl -s http://127.0.0.1:8410/healthz # ok, bot=dedinit_controller_bot, proxy, channels
.venv/bin/python -m crawler.telegram_crawler --all # краулер (инкрементально)
.venv/bin/python -m crawler.rss_crawler --all # RSS/Atom-краулер (условные GET, etag/modified; rss_state)
.venv/bin/python -m crawler.rss_crawler --source lwn --dry-run # сухой прогон без записи в БД
.venv/bin/python -m crawler.crawl_sources --all # фаза 1: сбор кандидатов в очередь (telegram+rss)
.venv/bin/python -m crawler.worker --workers 8 --limit 200 # фаза 3: параллельная обработка очереди (ThreadPoolExecutor)
MAX_CONCURRENT_LLM=2 .venv/bin/python -m crawler.worker --workers 8 # лимит одновременных LLM-запросов к Ollama
CLASSIFY_TIMEOUT=20 .venv/bin/python -m classifier.classify --db db/vesti.db --limit 200
openspec validate <change-name> # валидация change
```