Frust
Quitter Feedly impliquait de choisir un remplaçant auto-hébergé. Chaque option — Miniflux, FreshRSS, Tiny Tiny RSS — fonctionne comme un service web persistant : un port à exposer, une base de données à sauvegarder, un démon à relancer après une mise à jour noyau. Les fonctionnalités de filtrage que je voulais étaient de toute façon réservées aux abonnements premium. Frust a démarré comme un clone de Feedly, puis la question évidente s’est posée : pourquoi faire tourner un service ? Un agrégateur RSS se contente de récupérer des URLs et de produire des fichiers. Il suffit de le lancer depuis cron, d’écrire des fichiers statiques, et de les servir avec le serveur HTTP déjà en place. Pas de port, pas de base de données, pas de démon.
Fonctionnalités
Filtrage — inclure ou exclure des articles par mot-clé, expression ou regex ; chaque règle cible indépendamment le titre, le résumé ou le contenu complet
Regroupement — agréger plusieurs flux dans un seul fichier de sortie ; utile pour combiner des sources liées ou créer des digests thématiques
Texte complet forcé — quand un flux ne fournit qu’un résumé, un sélecteur CSS extrait le corps complet de l’article depuis la page source et l’injecte dans l’entrée du flux
Formats d’export multiples — le format de sortie est choisi par l’extension du fichier :
Extension Format .rss/.xmlRSS 2.0 .atomAtom 1.0 .jsonJSON Feed 1.1 .mdMarkdown avec entête YAML .epubEPUB 3.0 (flux groupés en livre) Enrichissement de flux — injecter du HTML personnalisé en haut ou en bas des articles (au niveau du flux, du groupe ou global) pour ajouter des boutons de favoris, des liens de partage ou des appels à des APIs externes comme Shiori
Import/export OPML — initialiser une configuration depuis une liste d’abonnements OPML existante ; exporter en OPML pour la portabilité
Export ZIP — regrouper un flux, un groupe ou la totalité de la sortie dans un ZIP pour transfert hors ligne ou archivage
Léger — écrit en Rust ; dépendances purement Rust (pas d’OpenSSL, pas de zlib) ; binaire statique MUSL utilisable sur tout Linux, y compris ARM
Sans état (stateless) — aucune base de données ; à lancer via cron, pas comme un démon en arrière-plan
Vie privée — pas de télémétrie ; s’exécute en utilisateur non-root ; sources sur Codeberg
Cas d’usage
Lecture hors ligne sur une liseuse. Regroupez une semaine de billets de fond en un seul EPUB et chargez-le sur un Kindle ou un Kobo. Aucune connexion nécessaire après la synchronisation — lisez dans l’avion, au jardin, partout.
Nettoyer les flux publicitaires. Les éditeurs mélangent contenu éditorial et articles sponsorisés. Un filtre keep: false sur « sponsored », « advertisement », « partenaire » les supprime de la sortie avant même que votre client ne les voie.
Récupérer les articles complets depuis les flux tronqués. Certains éditeurs coupent délibérément leurs flux pour forcer les visites web. L’option selector récupère la page source et injecte le corps complet dans l’entrée du flux — votre lecteur reçoit l’article entier.
Routeur ou NAS domestique. Le binaire ARM MUSL n’a aucune dépendance au runtime — déposez-le sur un routeur OpenWrt toujours allumé, un Raspberry Pi ou un NAS. Configurez une tâche cron pointant vers un répertoire de sortie servi par le serveur HTTP intégré de l’appareil.
Intégration avec un gestionnaire de favoris. Utilisez l’enrichissement de flux pour injecter un bouton « Enregistrer dans Shiori » dans chaque article, pré-rempli avec l’URL et le titre. Un clic depuis n’importe quel client qui affiche du HTML.
Comparaison
Miniflux, FreshRSS et Tiny Tiny RSS sont des lecteurs complets — ils incluent une interface web, des comptes utilisateurs et le suivi des articles lus. feedpushr est un agrégateur backend qui pousse les éléments vers des destinations externes. frust est le plus proche de feedpushr dans son rôle (pas d’interface lecteur), mais écrit des fichiers statiques au lieu de pousser vers une destination en direct.
| frust | Miniflux | FreshRSS | feedpushr | |
|---|---|---|---|---|
| Pas de service persistant (cron uniquement) | ✅ | ❌ | ❌ | ❌ |
| Pas de base de données | ✅ | ❌ PostgreSQL | ❌ MySQL/SQLite | ❌ BoltDB |
| Sortie en fichiers statiques | ✅ | ❌ | ❌ | ❌ |
| Export EPUB | ✅ | ❌ | ❌ | ❌ |
| Filtrage regex/mots-clés | ✅ | ✅ | ✅ | ✅ |
| Extraction du texte complet | ✅ sélecteur CSS | ✅ | ✅ XPath | ✅ plugin filtre |
| Push vers webhooks / APIs externes | ❌ | ❌ | ❌ | ✅ |
| Interface web / suivi de lecture | ❌ | ✅ | ✅ | ✅ |
| Binaire ARM entièrement statique | ✅ MUSL | Partiel | ❌ | Partiel (plugins AMD64 uniquement) |
L’absence d’interface web est intentionnelle : frust écrit des fichiers de flux standard consommables par n’importe quel client — Reeder, NetNewsWire, Fluent Reader, ou une instance Miniflux auto-hébergée pointant vers les fichiers statiques.
Installation
cargo install frustCross-compilation pour appareils ARM (routeurs, NAS, nano-ordinateurs) :
rustup target add armv7-unknown-linux-musleabihf
cargo install cross
cross build --release --target armv7-unknown-linux-musleabihf
# binaire statique dans target/armv7-unknown-linux-musleabihf/release/frustEntrée cron typique (toutes les 30 minutes) :
*/30 * * * * /usr/local/bin/frust /etc/frust/config.yaml >> /var/log/frust.log 2>&1