Mes Projets

XMLTV

J’ai eu l’idée de cette bibliothèque parce que nous voulions annuler notre abonnement au guide TV papier. Avec de jeunes enfants, ma femme et moi avons rarement le temps de regarder la télévision en direct — elle rattrape souvent les émissions en replay et consulte le programme TV une ou deux fois par semaine.

XMLTV est un format XML pour les données de guide électronique des programmes (EPG). J’ai écrit cette bibliothèque parce qu’il n’existait à l’époque aucune crate Rust pour lire ou écrire des fichiers XMLTV. Elle s’appuie sur serde pour la sérialisation et la désérialisation, et aplatit les balises vides comme <new/> en booléens pour réduire le code répétitif. Pour les gros fichiers, les programmes peuvent être lus un par un plutôt que chargés entièrement en RAM.

CLI

Le binaire xmltv est le compagnon tout-en-un. Il lit un fichier local (ou - pour l’entrée standard, ex. curl … | xmltv - -f json), applique une chaîne de filtres et écrit le résultat dans le format choisi. Installation : cargo install xmltv-cli ou récupérez un binaire depuis la page des releases.

Entrée & sortie

OptionDescription
FICHIERPositionnel. Fichier XMLTV d’entrée, ou - pour lire depuis stdin.
-l, --load <FICHIER>Charge les valeurs par défaut depuis un fichier de configuration JSON. Les options en ligne de commande sont prioritaires.
-m, --merge <FICHIER>Fusionne un autre fichier XMLTV. Répétable.
-o, --output <FICHIER>Écrit dans un fichier au lieu de stdout.
-f, --format <FMT>xml (défaut), json, ical, atom, jsonfeed.
--prettyIndente la sortie XML et JSON.

Filtrage

OptionDescription
-c, --channels <LISTE>Liste des chaînes à conserver séparées par des virgules (-c tf1,m6,Arte). Utilisez le préfixe id: pour un match sur l’identifiant uniquement. ? ouvre la sélection interactive dans le TUI.
-d, --days <N>Conserve aujourd’hui + les N jours suivants.
--date <AAAA-MM-JJ>Conserve les programmes commençant à cette date.
-s, --search <REQUÊTE>Recherche de sous-chaîne insensible à la casse sur le titre.
--category <CAT>Conserve les programmes de cette catégorie. Répétable, logique OU.
--time-slot <PLAGE>HH:MM-HH:MM, ou Mon-Fri 18:00-23:00, ou Sat,Sun 00:00-23:59. Répétable.
--time-slot-strictLe programme doit être entièrement contenu dans la plage.
--exclude-time-slotInverse la logique de plage horaire (exclure au lieu d’inclure).
--new-onlyConserve uniquement les programmes marqués <new/>.
--no-rerunsÉcarte les programmes marqués <previously-shown/>.
--lang <LANG>Préfère les titres/descriptions dans cette langue quand plusieurs sont proposés.
--min-rating <0.0–1.0>Note minimum en étoiles sous forme de fraction (0.6 ≈ 3/5).
--rating-system <SYS>Restreint --min-rating à un système de notation précis.

Transformation

OptionDescription
--cleanse <ÉLÉMENTS>Supprime les champs volumineux pour réduire la sortie. Valeurs : credits (ou un sous-ensemble plus fin : directors, actors, writers, adapters, producers, composers, editors, presenters, commentators, guests), categories, new, countries, keywords, sub-titles, languages, videos, audios, subtitles, last-chances, descriptions, dates, origin-languages, length, premieres, previously-showns, ratings, star-ratings, reviews, images, episode-nums, icons, urls.
-t, --timezone <TZ>Fuseau horaire de sortie : utc (défaut), local, ou un décalage comme +0100.
--sortTrie les programmes par heure de début à l’intérieur de chaque chaîne.
--deduplicateSupprime les doublons exacts (même chaîne, même début, même titre).
--tag <RÈGLE>Étiquetage automatique via TAG:CHAMP:MATCH:MOTIF (ex. --tag "News:title:contains:Journal"). CHAMP = title|description|channel, MATCH = contains|starts-with|ends-with. Répétable.

Inspection & outillage

OptionDescription
--list-channelsAffiche l’identifiant et le nom d’affichage des chaînes, puis quitte.
--statsRécapitulatif : nombre de chaînes, de programmes, plage de dates, taille du fichier.
--validateVérifie la structure du fichier et signale les erreurs sans produire de sortie.
--epgOuvre l’EPG embarqué en TUI (voir plus bas).
--pastInclut les jours passés dans la vue EPG.
--completions <SHELL>Génère le script d’auto-complétion pour bash, zsh ou fish.

Exemples

# JSON, les 3 prochains jours, trois chaînes uniquement
xmltv listings.xml -f json -d 3 -c "TF1.fr,France2.fr,Arte.tv"

# Soirées en semaine + week-ends complets
xmltv listings.xml --time-slot "Mon-Fri 18:00-23:00" --time-slot "Sat,Sun 00:00-23:59"

# Fusion de deux sources, sans les métadonnées volumineuses
xmltv main.xml -m secondary.xml --cleanse "credits,images,episode-nums"

# Extrait les matchs de football dans un fichier de calendrier
xmltv listings.xml -s "Football" -f ical -o sports.ics

EPG en TUI embarqué

xmltv … --epg ouvre un EPG interactif en terminal construit avec ratatui et crossterm. Il affiche les mêmes données que la sortie CLI mais sous forme de grille navigable : chaînes à gauche (avec icônes quand le terminal supporte les protocoles graphiques Kitty, Sixel ou half-blocks via ratatui-image), axe temporel en haut, blocs de programmes au centre et panneau de détails pour la sélection courante. Les icônes de chaînes sont préchargées en parallèle avec rayon avant l’entrée dans l’écran alternatif, ce qui garde le défilement fluide. Le popup de sélection de chaînes (-c ?) sert aussi de filtre interactif pour la CLI.

Page web statique

Pour partager la grille dans un navigateur (PC, tablette, mobile), le dépôt embarque une page statique sans dépendances : un index.html, un styles.css, un app.js, ni framework ni bundler. Elle lit un fichier xmltv.json produit par la CLI :

xmltv listings.xml -f json -d 3 -o xmltv.json --pretty

Placez xmltv.json à côté de index.html, servez les deux par n’importe quel serveur HTTP statique (python3 -m http.server, Nginx, Caddy, GitHub Pages, S3), et la page s’affiche. Fonctionnalités :

Un build.sh optionnel (un pipeline awk d’environ 40 lignes — sans npm, sans node) inline le CSS et le JS dans un unique dist/index.html pour distribuer sur un routeur OpenWRT ou autre ; seul xmltv.json reste externe.

Dépôt · crates.io · lib.rs