Article écrit par Eddie Barraco
Hey Reed ! Je viens de jouer à un super jeu. Tu connais ? https://www.youtube.com/watch?v=fWlHjpKmvh8
Je clique, ça s’ouvre sur mon navigateur web. Mhhh… Pourquoi mon environnement ne l’ouvre-t-il pas automatiquement avec mpv ? Pour lire une vidéo Youtube, je n’ai pas besoin de passer par mon navigateur web. Ça me ferait gagner du temps, de la bande passante et me ferais éviter les pubs.
Et puis d’ailleurs, comment ça marche tout ça ? Comment mon environnement peut-il deviner quel programme attacher à tel chemin ? Est-ce que c’est configurable ? Est-ce que je contrôle tout ça ?
C’est le sujet que je souhaite présenter aujourd’hui !
En préquel, je souhaiterais apporter quelques précisions. Les outils et protocoles que je vais présenter sont valides dans un environnement Linux. Je n’ai pas d’expérience sur de possibles compatibilité macOS ou Windows. Si vous êtes sur ces systèmes d’exploitation, bon lèche-vitrine à vous.
Présentation de xdg-open
xdg-open est l’outil communément utilisé sous Linux. La documentation Ubuntu précise ceci :
La commande xdg-open utilisée dans un terminal, permet de lancer le logiciel par défaut correspondant à la fois à votre variante et au type de fichier ou d’action qui vous intéresse :
Exemple :
xdg-open /etc/fstab
ouvrira fstab
avec gedit, si votre variante est Ubuntu,
avec kate, (Kubuntu),
avec pluma, (Mate),
avec mousepad, (Xubuntu),
avec leafpad, (Lubuntu).
Il est également automatiquement utilisé par les différents programmes comme votre terminal. Cliquer sur une URL est c’est xdg-open qui est appelé.
Concrètement ce script a associé un logiciel (kate) à un type de fichier (plain text) et une distribution (Kubuntu). Cette association est fixe et codée en dur dans le script. Vous ne pouvez visiblement pas ouvrir gvim via xdg-open sous Kubuntu…
Voyons le bon côté des choses : xdg-open est une interface appelée par nos WM et nos applications. Nous pouvons toujours créer le nôtre. Cet exemple est de plus idéal pour présenter ma façon d’automatiser mes systèmes.
Nos briques élémentaires
Pour mener à bien notre mission nous allons utiliser plusieurs intermédiaires minimalistes. Nous voulons séparer nos responsabilités et rendre le tout lisible. Une chose à la fois, et les hippopotames, seront bien gardés !
Ouvrir un fichier local
C’est notre première étape. Définissons ensemble comment ouvrir nos PDF, images, musiques et autres fichiers de nos disques.
Pour ouvrir un fichier local, je propose de nous reposer sur un protocole et une nomenclature déjà bien existante. Connaissez-vous Mailcap ?
Mailcap est un format déclaratif qui associe un type de fichier à des programmes. Un exemple de Mailcap pourrait être :
# ~/.mailcap text/*; less -f %s video/*; mpv %s; test=test -n "$DISPLAY" audio/*; mpv %s application/pdf; evince %s application/x-cbr; YACReader %s
Comme vous pouvez le constater c’est vraiment très simple. Il existe même certaines subtilités pour faire un test et déterminer si la ligne s’applique.
Pour utiliser ce fichier, j’utilise actuellement un paquet run-mailcap. Plusieurs exécutables sont communément offerts par les différentes implémentations mais celle qui va nous intéresser est :
$ see toto.txt
Concrètement le type de fichier (on parle ici de MIME type) est déterminé en amont par différents utilitaires dont file. Ensuite, le fichier .mailcap
est traité et le programme correspondant est utilisé.
Ouvrir une URL
On peut ouvrir des fichiers locaux comme on le souhaite. On peut configurer le programme à utiliser. Grande victoire ! Mais qu’en est-il de nos URLs ? Un lien Peertube n’est pas un fichier local. Qu’allons-nous devenir ? Pas de panique, nous devons tisser davantage notre toile !
Mailcap fonctionne bien quand il s’agit de fichiers locaux. En revanche, il est inapproprié lorsqu’on parle d’URL. En effet, il est impossible de déterminer le mime type d’une ressource distante sans la demander. Or il n’est pas question de tout télécharger brutalement pour ensuite tester le MIME type du fichier. Nous allons donc devoir trouver une méthode plus intelligente.
Nous allons utiliser des règles regex pour associer les MIME types. Un fichier de configuration pourrait être :
# url-mimes.conf image/x-gif .*gif$ image/x-image .*((png|jpg|gif))$ video/x-youtube https://www.youtube.com/watch ? video/x-youtube https://youtu.be/ video/x-peertube https://.*/videos/watch/.* video/x-reddit https://v.redd.it/.............
Le format des regex peut vous sembler étrange. Nous utilisons ici le format utilisé par expr qui permet de vérifier le match de chaines de caractères via la forme expr "foo" : ".oo"
. Expr est un utilitaire POSIX donc majoritairement compatible avec les interpréteurs de scripts.
Un simple script url-guessmime est capable de traiter cette configuration et de nous renvoyer le MIME type de l’URL passé en argument.
Utilisons ceci dans un second script url-open qui va lui ouvrir l’URL avec le bon Mailcap. Ici un video/x-youtube
est un video/*
et peut donc être ouvert par mpv.
Ouvrir un protocole
C’est bien joli tout ça mais concrètement nous on s’en fiche un peu. Je n’ai pas envie de taper
$ url-open https://www…
à chaque fois ! Et ton truc là,xdg-open
, il est où dans cette histoire ?
Ah, j’y viens ! xdg-open sera notre point d’entré pour unifier tout ça. Mais j’avais d’abord besoin de vous présenter les pions un par un.
Nous avons précédemment parlé d’URL HTTP. Pourtant il y a bien d’autres types de protocoles que nous voulons gérer (HTTP, SSH, mailto, lutris, steam, etc). Au passage, le protocole file est aussi un moyen de représenter une URL d’un fichier local.
Nous avons besoin de nouvelles (et dernières) associations ! Ne faites pas la tête !
# protocols.conf file: see http: url-open {} || $BROWSER {} https: url-open {} || $BROWSER {} mailto: $PREFTERM -e neomutt lutris: lutris rtmp: vlc
Ici comme vous pouvez le voir je viens préciser quelle commande exécuter en fonction du protocole. Notre dernier script xdg-open permet de le lire et d’exécuter la commande associée.
Et c’est ici que la magie se produit. Que vous réalisez que tout est lié et qu’on peut désormais faire ce qu’on veut.
Vous remarquez au passage que je peux utiliser des délimiteurs shell. Ici si url-open échoue à trouver et lancer le bon programme, je laisse mon navigateur traiter l’URL.
$ xdg-open https://skeptikon.fr/videos/watch/b7af5d90-ea5f-437b-b0bf-542c4e9176b8 mpv https://skeptikon.fr/videos/watch/b7af5d90-ea5f-437b-b0bf-542c4e9176b8 $ xdg-open file://downloads/foo.pdf evince downloads/foo.pdf $ xdg-open movies/back-to-the-future.mp4 mpv movies/back-to-the-future.mp4
Victoire ! Nous avons enfin une solution complète et configurable. Nous pouvons lancer n’importe quoi avec n’importe quel logiciel !
Mais que se passe-t-il si on n’a pas encore configuré les règles pour traiter une URL ou un MIME type ?
Pas de panique, notre xdg-open lancera un script de secours xdg-requestopen si rien n’a marché. Ce dernier demande ouvertement à l’utilisateur comment lancer l’URL.
Qu’en conclure ?
À travers cet exemple je souhaitais surtout démontrer qu’on pouvait répondre à une problématique assez complexe tout en écrivant des petits scripts très simples.
Aucun de ces scripts n’est parfait et ils ont tous été écrits en moins de 15 minutes. Pourtant ils me font aujourd’hui gagner énormément de temps au quotidien et m’apportent une solution configurable et résiliente.
Donc n’ayez pas peur d’automatiser ce que vous faites fréquemment. Il est possible avec un langage très simple et ultra compatible de faire à peu près n’importe quoi.
Passez une bonne fin de journée / soirée / nuit / thanksgiving et amusez-vous à coder.