mirror of
https://gitverse.ru/kpa39l/vesti.git
synced 2026-09-29 18:05:03 +00:00
4.0 KiB
4.0 KiB
rss-formatting-preserve: сохранять форматирование RSS-новостей (абзацы, разметка)
Why
Пользователь: в RSS omarchy внутри текста новости есть HTML-символы, а мы их «выкидываем» из текста, из-за чего вся новость в предпросмотре отображается сплошным текстом, ничего не понять. Нужно при скачивании из источников RSS сохранять заложенное форматирование.
Разбор:
html_to_text()(crawler/rss_crawler.py) режет HTML корректно, но без разделителей между блочными элементами (p/li/h1-6/blockquote) — абзацы/списки сливаются в один кусок.- После этого
re.sub(r"\s+", " ", text)(стр. 143) схлопывает и переносы строк — даже если бы были\n\n, они превращаются в один пробел. Итог: «сплошной текст». - В вебе
md_filter(web/app.py) вызывается наtextиз RSS — синтаксис HTML (b/i/a) экранируется и виден как текст-каша, а markdown-разметки в RSS-тексте нет.
Design
1. Краулер: сохранять структуру абзацев
html_to_text():
- после удаления script/style/noscript — вставлять переносы-разделители вокруг блочных
тегов (p, div, li, h1–h6, blockquote, pre, tr), чтобы они давали
\n\nмежду абзацами и\nвнутри list-item. - текст по-прежнему plain (в БД хранится текст, а не HTML) — просто читаемая структура.
parse_entries() (стр. 143): заменить re.sub(r"\s+", " ", text) на нормализацию:
- схлопывать 3+ переноса до 2 (максимум пустая строка между абзацами);
- убирать горизонтальные пробелы в начале/конце строк и перед переносами;
- пробелы внутри строки НЕ трогать (сохраняются слова/URL).
2. Веб: безопасный рендер HTML-разметки из RSS
Исходный текст поста (RSS) в предпросмотре (кандидаты, отобранные) — рендерить как безопасный HTML подмножеством тегов, а не экранировать в тёмную кашу:
- новый фильтр
safe_htmlв web/app.py на основеbleach:bleach.clean(text, tags=ALLOWED, attributes={'a': ['href', 'title']}, protocols=['http','https'])+bleach.linkify; - применяется ТОЛЬКО к
text(оригинал из RSS) в candidates.html и selected.html; - markdown-фильтр (
md_filter) остаётся для пересказов/комментариев (markdown от модели).
Публикация (publisher/card.py) не меняется: в канал уходит plain text, абзацы \n\n
будут сохранены — Telegram корректно отобразит переносы.
Безопасность
safe_html— allowlist-санитайзер (bleach): никаких script/style/iframe/on*, href только http(s), linkify распознаёт ссылки. XSS-поверхности нет.md_filterне меняется (остаётся escape→markdown).
Files
- crawler/rss_crawler.py — html_to_text(), parse_entries() (абзацы, нормализация).
- web/app.py — фильтр safe_html (bleach).
- web/templates/candidates.html —
{{ selected.text | safe_html }}. - web/templates/selected.html —
{{ selected.text | safe_html }}. - requirements.txt — +bleach.