feat(M5): source blog RSS — fetch, parsing, déduplication et état persistant
Implémentation complète de la source blog RSS du collège : - BlogRSSClient (sources/blog/rss.py) : client sans état récupérant et parsant le flux via feedparser, avec déduplication par ensemble de GUIDs connus, cache HTTP conditionnel (ETag/Last-Modified), conversion HTML→texte (BeautifulSoup), tri déterministe (date desc puis id asc), et mode dégradé (flux invalide/erreur → warning expurgé + liste vide). - BlogRSSFetchResult (sources/blog/result.py) : résultat immuable contenant articles, en-têtes de cache et indicateur not_modified. - BlogRSSState (sources/blog/state.py) : persistance JSON tolérante (GUIDs triés, version, ETag, Last-Modified) avec redaction des chemins dans les logs. - Fixture tests/fixtures/blog_rss.xml : flux RSS 2.0 anonymisé, 3 articles, dates fixes, ordre non chronologique. - 38 tests unitaires (22 client + 16 state) couvrant parsing nominal, déduplication intra-flux, 304, bozo, erreurs réseau, non-fuite de secrets, tri secondaire, persistance d'état et tolérance aux fichiers corrompus. - Documentation : TODO.md M5 coché, GUIDE_DEV_PYTHON.md §5 bis aligné avec l'API livrée (known_guids, BlogRSSFetchResult, BlogRSSState). - Configuration : feedparser ajouté aux additional_dependencies du hook mypy pre-commit pour aligner l'environnement isolé avec le .venv. Co-authored-by: opencode/coder <coder@agents.invalid> Co-authored-by: opencode/test-engineer <test-engineer@agents.invalid>
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
"""Source du blog du collège : récupération et suivi du flux RSS.
|
||||
|
||||
Ce package expose l'API publique du connecteur du blog du collège :
|
||||
|
||||
- :class:`BlogRSSClient` (:mod:`pronote_sync.sources.blog.rss`) : télécharge
|
||||
et parse le flux RSS, déduplique les entrées par GUID et renvoie les
|
||||
nouveaux articles dans un :class:`BlogRSSFetchResult`.
|
||||
- :class:`BlogRSSFetchResult` (:mod:`pronote_sync.sources.blog.result`) :
|
||||
type de retour figé d'une récupération : nouveaux articles, en-têtes
|
||||
HTTP de cache (``ETag``/``Last-Modified``) et indicateur ``304 Not
|
||||
Modified``.
|
||||
- :class:`BlogRSSState` (:mod:`pronote_sync.sources.blog.state`) : état
|
||||
local persistant (GUID connus et en-têtes de cache) pour la
|
||||
déduplication et les requêtes conditionnelles.
|
||||
"""
|
||||
|
||||
from pronote_sync.sources.blog.result import BlogRSSFetchResult
|
||||
from pronote_sync.sources.blog.rss import BlogRSSClient
|
||||
from pronote_sync.sources.blog.state import BlogRSSState
|
||||
|
||||
__all__ = ["BlogRSSClient", "BlogRSSFetchResult", "BlogRSSState"]
|
||||
|
||||
Reference in New Issue
Block a user