Files

48 lines
3.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tasks: rss-crawler
## 1. Схема и конфиг
- [x] 1.1 db/schema.sql: + CREATE TABLE rss_state; sources + feed_url; db/db.py — миграция ALTER TABLE (feed_url); sources.py — синк feed_url
Проверка: `python -m db.db` (init_db) выполняется без ошибок; таблица rss_state и колонка sources.feed_url появляются
- [x] 1.2 config.py: + RSS_USER_AGENT (env, default "vesti-rss/0.1"), RSS_DEFAULT_TIMEOUT=20
Проверка: `python -c "from config import RSS_USER_AGENT; print(RSS_USER_AGENT)"` → значение из .env
- [x] 1.3 requirements.txt: + trafilatura, selectolax
Проверка: `.venv/bin/pip install -r requirements.txt` без ошибок
## 2. Модуль краулера
- [x] 2.1 crawler/rss_crawler.py: normalize_url (UTM/якоря), sha256_text
Проверка: изолированный тест normalize_url: utm-параметры удаляются, якорь удаляется, остальное сохраняется
- [x] 2.2 fetch_feed: httpx.GET с If-None-Match/If-Modified-Since/User-Agent, таймаут, ретрай 429/503; 304 → пусто
Проверка: повторный запрос к ленте с etag → 304 (сервер LWN поддерживает)
- [x] 2.3 parse_entries: feedparser, извлечение etag/modified из ответа, лимит записей (MAX_ITEMS=25)
Проверка: запись → dict {url, title, text, published_at, author}
- [x] 2.4 full_text: trafilatura для summary-only (selectolax для HTML→text)
Проверка: запись с summary → в text полный текст или summary (не падает)
- [x] 2.5 store_rss_post: дедуп по sha256; вставка в posts (source_id, url, canonical_url, content_type='text', published_at)
Проверка: две идентичные записи → одна строка в posts
- [x] 2.6 run_source: start_run/finish_run, обновление rss_state (etag/modified/status/error_count), status alive/dead при error_count>=5
Проверка: успешный прогон → rss_state.status='alive', runs=ok; имитация ошибки → error_count растёт
- [x] 2.7 CLI: --all / --direction / --source / --dry-run
Проверка: `--source lwn --dry-run` печатает записи, БД не меняется
## 3. Источники и интеграция
- [x] 3.1 sources.yaml: + lwn (crawler: rss, direction: linux, priority: P0, enabled: true); пример opennet закомментирован
Проверка: `sync_sources_to_db()` — в БД появляется источник lwn c crawler='rss'
- [x] 3.2 .env.example: + RSS_USER_AGENT, RSS_DEFAULT_TIMEOUT
- [x] 3.3 Реальный прогон `--source lwn` → посты в posts, rss_state настроена
Проверка: SQL-запросы из design.md (Verification)
## 4. Cron и доки
- [ ] 4.1 Hermes cron: vesti-rss-crawler (`*/15`, P0; no_agent, тихий, deliver=local)
Проверка: cron list показывает job; ручной запуск проходит
- [x] 4.2 STATUS.md / AGENT.MD обновлены (команды запуска, порты/доступы)
Проверка: grep rss в доках
- [x] 4.3 `openspec validate rss-crawler` → 0 ошибок
Проверка: команда выше → valid
- [ ] 4.4 TODO.md: + задача веб-скедулинга RSS (веб-админ: кнопка запуска краулера)
Проверка: задача видна в планах
Открытый вопрос: состояние таблицы rss_state ERROR (после 429 и ретрая, error_count=1) обновится при следующем удачном 200; в отсутствие ошибок не трогаем.