This commit is contained in:
bvn13 2026-03-23 12:45:37 +03:00
parent 324cd8a959
commit e4f8dc0987
2 changed files with 40 additions and 9 deletions

31
docs/update-7.md Normal file
View File

@ -0,0 +1,31 @@
# Обновление 7 — Пропускать OOB если URL картинки содержит недопустимые символы
## Контекст
В update-5 была добавлена нормализация URL картинок: символ `:` в path кодировался как `%3A`.
Выяснилось, что CDN принимает закодированный URL (200 OK), но клиент Conversations
всё равно не отображает картинку — причина в hotlink protection на стороне CDN.
Таким образом, нормализация URL не решает проблему и бесполезна.
Практическое наблюдение: URL с `:` в path — признак CDN с hotlink protection.
Такие картинки не отобразятся в клиентах в любом случае.
Решение: не добавлять OOB для URL, содержащих `:` в path-части.
## Задача
1. В `adapters/sources/rss/fetcher.py`:
- Удалить функцию `_normalize_image_url` и импорты `urllib.parse`
- В `_extract_image_url` проверять raw URL: если path-часть содержит `:` — возвращать `None`
## Техническая реализация
Проверка выполняется через `urlparse`:
```python
from urllib.parse import urlparse
p = urlparse(url)
if ':' in p.path:
return None
return url
```

View File

@ -3,7 +3,7 @@ import logging
import re import re
from html import unescape from html import unescape
from typing import List, Optional from typing import List, Optional
from urllib.parse import quote, urlparse, urlunparse from urllib.parse import urlparse
import feedparser import feedparser
@ -20,18 +20,18 @@ def _strip_html(text: str) -> str:
return unescape(text).strip() return unescape(text).strip()
def _normalize_image_url(url: str) -> str:
"""URL-энкодирует path-часть, чтобы символы вроде ':' не ломали парсеры клиентов."""
p = urlparse(url)
return urlunparse(p._replace(path=quote(p.path, safe='/')))
def _extract_image_url(entry) -> Optional[str]: def _extract_image_url(entry) -> Optional[str]:
"""Возвращает нормализованный URL первого enclosure с type image/*.""" """Возвращает URL первого enclosure с type image/*.
Возвращает None если URL содержит ':' в path признак hotlink-защищённого CDN.
"""
for enc in entry.get("enclosures", []): for enc in entry.get("enclosures", []):
if enc.get("type", "").startswith("image/"): if enc.get("type", "").startswith("image/"):
raw = enc.get("href") or enc.get("url") raw = enc.get("href") or enc.get("url")
return _normalize_image_url(raw) if raw else None if not raw:
return None
if ":" in urlparse(raw).path:
return None
return raw
return None return None