27. Git et les branches

Git est un formidable outil de suivi de version que j’utilise quotidiennement pour mes scripts (LaTeX, python, bash, …). Il n’est pas nécessaire de faire de la programmation pour l’utiliser. Je vais ici présenter la manière de réaliser un travail sur deux branches d’un script LaTeX versionné sous git.

La raison du passage sur une autre branche que « master » tient dans l’évolution du module « siunits » vers la version plus performante « siunitx ». Ces deux modules sont incompatibles, car la commande principale « \units{…}{…} » du premier a été remplacée par « \SI{…}{…} » dans le second. Or, le nombre d’occurrences de cette commande dans mon script étant important et des spécificités d’écritures propres au module « siunits » étant possibles, il était dangereux de travailler directement sur la branche « master ». On va donc créer une branche « unites », travailler sur celle-ci et quand toutes les modifications seront faites et que la compilation sera à nouveau fonctionnelle, on fusionnera les modifications faites dans la branche « unites » dans « master ».

Voici comment on peut procéder. Avant de créer une nouvelle branche, on vérifie qu’il n’existe que la branche master grâce à la commande :

git branch

qui devrait retourner « master » (en pressant sur Q on revient à l’invite de commande). On peut voir l’ensemble des branches avec leur dernier commit grâce à :

git branch -v

Avant le nom de la branche se trouve une étoile (*) qui montre la branche sur laquelle on se trouve actuellement.

On crée alors la nouvelle branche ainsi :

git branch unites

La commande « git branch » précédente retourne alors non seulement « master » mais aussi « unites ». La branche « master » reste cependant la branche de travail, comme le montre la présence de l’étoile devant celle-ci.

La branche « unites » est donc créée. Mais si on effectue des modifications sur les fichiers du dépôt, ces modifications seront reportées sur la branche « master ».

Pour changer de branches, il faut utiliser :

git checkout unites

La commande « git branch » présente alors une étoile devant la branche « unites ». On est sur la nouvelle branche.

On peut alors effectuer des modifications sur les fichiers du dépôt, comme par exemple, ajouter une ligne de commentaire : « % blabla » dans le fichier principal, main.tex par exemple.

Ensuite, on vérifie que les changements existent pour cette branche :

git status

Puis, on les ajoute pour le commit :

git add .

On effectue le commit :

git commit -m 'Ajout commentaire'

Et on verse ce commit au dépôt :

git push -u origin unites

et non :

git push -u origin master

puisque sur le dépôt « origin », on veut atteindre la branche « unites ».

Si maintenant, on veut revenir à la branche « master », il faut savoir qu’il est nécessaire d’avoir réalisé toutes les opérations de commit précédemment. Sans quoi le changement ne sera pas autorisé.


Et là on assiste à un miracle. Oui, oui, un miracle. Car en revenant à la branche « master » par :

git checkout master

et en éditant le fichier main.tex, on peut constater la disparition du commentaire.

Pour moi, c’est simplement fou, car cela signifie qu’en changeant de branche, l’ensemble des modifications réalisées sur la branche « unites » a été annulé. Toutes les modifications ont disparu. Et quand on retourne sur la branche « unites », le miracle continue, le commentaire réapparaît, ce qui signifie que toutes les modifications sont revenues.

On peut ainsi, sur la branche « unites » effectuer une compilation, qui peut bien ou mal se dérouler, quand on reviendra sur la branche « master », tous les fichiers issus de la compilation du main.tex de cette branche seront restaurés et une nouvelle compilation se déroulera correctement.

Il faut renouveler le WAHOO du miracle qui s’est accompli et évidemment les milliers de merci à tous les développeurs qui nous fournissent avec bienveillance cet outil formidable.


Après qu’une branche ait été créée, en n’oubliant pas de s’y placer par un checkout, on peut donc travailler en toute tranquillité sur celle-ci. Dans mon cas, j’ai remplacé le module siunits par siunitx dans un fichier contenant le préambule de mon fichier .tex principal. Puis, dans plein d’autres fichiers, j’ai du changer la commande LaTeX \unit{…}, propre au module siunits, par la commande \SI{…} propre au module siunitx. De plus, pour écrire un symbole d’unité pour l’ampère, par exemple, siunits permet \ampere, alors que siunitx demande \si{\ampere}. Enfin, les chiffres ne pouvant être notés comme \SI{10’000\cdot 10^3}{\metre}, par exemple, en raison du séparateur des milliers et du \cdot, il a fallu convertir cela en \SI{10000e3}{\metre} pour que la compilation fonctionne. Ce fut long.

Entre temps, je pouvais à loisir continuer de travailler sur la branche master pour avancer à la rédaction de mon cours. C’est incroyablement pratique.


Et enfin venu le moment où j’ai fini les modifications liées au module siunitx. Sur la branche unites, j’ai fait une dernière compilation pour vérifier que tout se passait bien et ai considéré la migration du module siunits vers siunitx comme terminée.

Il fallait maintenant fusionner les deux branches, ou plutôt, fusionner la branche unites dans la branche master. Pour ce faire, il faut d’abord de placer sur la branche dans laquelle la fusion doit être réalisée :

git checkout master

Puis, très simplement, faire la fusion :

git merge unites

En quelques secondes tout était prêt. Aucun conflit n’ayant été détecté, j’ai simplement compilé le fichier .tex principal de mon cours pour voir si tout avait bien fonctionné. Ce fut le cas. Tout les changements effectués sur la branche unites étaient passés dans la branche master et celle-ci compilait parfaitement.

Restait une dernière étape à réaliser. Comme aucun changement n’étaient plus à faire sur la branche unites, il fallait la supprimer :

git branch -d unites

Restait en fin à pousser tout cela sur le dépôt distant :

git status
git add .
git commit -m 'Fusion de la branche unites réalisée'
git push origin master

Ce fut une vraie partie de plaisir que je vous souhaite.

23. Email, mon amour !

Je reproduit ici un magnifique texte d’un écrivain électronique @ploum qui, non content de nous livrer une pensée fort intéressante, la publie sous différents formats, mais en licence libre (CC-By BE). Se trouve après celui-ci une critique qui, me semble-t-il, permet de dépasser son propos.

Je me suis surpris à envoyer un long email à une personne que je suis depuis plusieurs années sur les réseaux sociaux. J’ai pris le temps de rédiger cet email. De le relire. De le corriger. De l’affiner. J’y exprime une idée simple que j’aurai pu lui envoyer sur Twitter, que ce soit en le mentionnant ou en messagerie privée. Je lui dis, tout simplement, que je ne souhaite plus interagir sur Twitter.

Le fait de prendre du temps, de réfléchir, de me relire m’a procuré un énorme plaisir. J’avais l’impression d’avoir apporté un petit quelque chose au monde, une clarification de mes idées, une main tendue, une piste de réflexion partagée. J’ai construit quelque chose d’intime, où je me révèle.

En tentant de regagner le contrôle de mon cerveau, j’ai retrouvé, sans le vouloir, l’art désuet de la relation épistolaire.

Nous avons oublié l’importance et la facilité de l’email. Nous l’avons oublié, car nous n’en avons pas pris soin. Nous laissons notre boîte aux lettres pourrir sous des milliers de messages non sollicités, nous perfectionnons volontairement l’art de remplir nos boîtes de courriels inutiles, inintéressants, ennuyeux sans plus jamais prendre le temps d’y déposer un courrier utile, écrit, intime.

Nous croyons que le mail est ennuyeux alors que ce sont nos pensées qui sont obscurément désertes. « Ce qui se conçoit bien s’énonce clairement et les mots pour le dire viennent aisément », disait Boileau. Force est de constater que nos cerveaux sont désormais d’infernaux capharnaüms assiégés par d’innombrables tentatives de les remplir encore et encore. Anesthésiés par la quantité d’informations, nous ne trouvons d’échappatoire que dans la consommation.

Souhaitant soigner ma dépendance à Twitter, j’avais décidé de ne plus suivre que quelques comptes sélectionnés dans mon lecteur RSS grâce à l’interface Nitter. En quelques semaines, une froide vérité s’est imposée à moi : rien n’était intéressant. Nous postons du vide, du bruit. Une fois ôtées les fonctionnalités affriolantes, les notifications, les commentaires, le contenu brut s’avère misérable, souffreteux. J’avais pourtant sélectionné les comptes Twitter de personnes particulièrement intéressantes et intelligentes selon mes critères. Las ! Nous nous complaisons tous dans la même fange d’indignation face à une actualité très ciblée, le tout saupoudré d’autocongratulation. Réduite à quelques caractères, même l’idée la plus enrichissante se transforme en bouillie prédigérée conçue pour peupler un hypnotique défilement ininterrompu.

Un soir, alors que je profitais de ma douche pour articuler un concept théorique qui m’occupait l’esprit, j’ai réalisé avec effroi que je pensais en threads Twitter. Mon esprit était en train de diviser mon idée en blocs de 280 caractères. Pour le rendre plus digeste, plus populaire. J’optimisais spontanément certaines phrases pour les rendre plus « retweetables ».

En échange d’un contenu de piètre qualité, Twitter déformait mes pensées au point de transformer mon aquatique méditation vespérale en quête semi-consciente de glorioles et d’approbations immédiates. Le prix payé est inimaginable, exorbitant.

Ayant bloqué tous les sites d’actualité depuis belle lurette, je décidai que Twitter et Mastodon allaient suivre le même régime que Facebook et Linkedin : ne plus suivre personne. Je nourris désormais ma sérendipité d’écrits plus longs grâce à l’ancienne magie vaudoue du RSS.

Libéré, aéré, le cerveau retrouve soudain de la souplesse, de l’amplitude. Au détour d’une blague dans un forum que je suis, je crois deviner qu’un politicien a été mis en prison. L’information m’agresse. Elle occupe une place imméritée dans mon cerveau. Je n’avais pas envie de savoir cet inutile artefact qui sera vite effacé de la conscience publique. Comme un ancien fumeur soudainement allergique à la fumée, mon cerveau ne peut plus supporter les déchets pseudo-informationnels dont nous sommes abreuvés par tous les pores, par tous les écrans, par toutes les conversations.

Une fois débarrassé de cette gangue d’immondices, je me surprends à penser. Mes doigts se surprennent à vouloir écrire plutôt qu’à rafraîchir une page et réagir avec une émotion préfabriquée. Au lieu d’une démonstration publique de mon égotique fierté travestie en succédané de communication, j’ai envie de forger des textes, des histoires, de faire passer une information dans un contexte plus large, de lui donner le temps d’exister dans l’esprit des récipients. Et tant pis si ces derniers sont moins nombreux, moins enclins à m’injecter leurs likes chargés de dopamine.

Devant ma boîte aux lettres, immaculées grâce à une stricte observance des mes règles inbox 0 et de désabonnement, je guetterai la réponse comme un adolescent attend le facteur lui tendant une enveloppe parfumée. Et si elle ne vient pas, ma vie continuera sans que je sois obnubilé par un compteur de vues, de likes ou de partages.

L’outil de communication décentralisé web 5.0, 6.0 et 12000.0 existe déjà. C’est l’email. Nous n’avons tout simplement pas encore vraiment appris à l’utiliser. Nous tentons vainement de le remplacer ou de l’améliorer à grands coups d’interfaces et de fonctionnalités multicolores, car il expose la vacuité de nos interactions. Il met à nu que nous devrions faire un effort, changer notre cerveau et notre volonté. Tant que nous nous évertuerons à produire et consommer le plus de bruit possible en insatiables gloutonneries, tant que nous mesurerons notre succès avec d’autocrates statistiques, aucun système ne nous permettra de communiquer. Parce que ce n’est pas ce que nous cherchons. Parce que nous nous sommes perdus dans l’apparence et la quantité, jetant aux oubliettes l’idée même de qualité. Nous critiquons la faiblesse d’esprit et le court-termisme de nos politiciens sans réaliser que nous moquons notre propre reflet.

Lorsque nous serons assez mûrs pour tout simplement vouloir échanger de l’information de qualité, nous découvrirons que la solution était sous nos yeux. Si simple, si belle, si élégante, si décentralisée.

L’email.

@ploum

Il faut relever que si ce texte met en évidence une autre manière de considérer le mail que comme un moyen d’envoyer de petits messages et relève bien le plaisir qu’il y a prendre le temps d’écrire des textes longs, la stigmatisation de l’écologie réalisée dans un autre texte par son auteur montre que les raisons de son intérêt pour l’email sont exclusivement celles d’un écrivain et que son efficacité en terme de relation entre le contenu et l’énergie dépensée n’est pas comprise.

Dans un autre texte sur le « Minimalisme numérique », dont l’objectif n’est pas une décroissance des besoins, mais une meilleure efficacité de besoins, en admettant que chacun définisse ceux-ci selon son bon vouloir, il adopte certes un point de vue intelligent parce qu’une absence d’efficacité est stupide, mais il néglige les modifications salutaires que des changement de pratiques peuvent avoir sur nous. Ainsi, son point de vue est de retrouver le plaisir d’écrire par l’utilisation d’email long, mais pas de trouver celui-ci dans la recherche d’un minimalisme énergétique. Les outils qu’il décrit ensuite, comme son utilisation d’un mac et d’un téléphone android en spécifiant simplement que les autres portables sont trop lourds et que le fairphone ne le convainc pas, montrent que l’idée de minimalisme qu’il soutient limite considérablement son évolution et que les principes du libre n’ont pas pour lui de conséquences écologiques.

Ce qui limite la porté de ce néanmoins beau texte.

22. Éditer du texte en ligne de commande : vi

Ne tournons pas autour du pot, nous allons parler de vim et pas de emacs, même si les idées de RMS sont dans mon cœur.

Pendant longtemps, j’ai utilisé vi comme éditeur de texte en étant persuadé je j’utilisais vim. Puis un jour, après avoir configuré mutt (maileur en ligne de commande) pour utiliser vi, j’ai eu besoin de la correction orthographique. Or, tout ce que j’ai tenté de faire pour y parvenir n’a pas fonctionné jusqu’au moment où j’ai regardé si vim était bien installé. Il ne l’était pas. J’utilisais vi dans sa nudité la plus pure sous Debian. J’ai donc installé vim et beaucoup de choses sont apparues qui m’ont donné envie d’écrire cet article.

Configuration

La configuration de vim se fait dans le fichier ~/.vimrc. Voici une configuration très simple qui permet de voir comment cela fonctionne :

ab moi Machin Truc <machin.truc@chose.org>
" Un commentaire
set mouse=a
set number
set spell
set t_Co=256
map <F2> :set spell!<CR>
set spelllang=fr,en
hi SpellBad ctermfg=Red ctermbg=NONE

La première ligne crée un alias. En tapant « moi » dans vim suivi d’un espace, le texte « moi » sera remplacé par « Machin Truc <machin.truc@chose.org> ».
Ensuite se trouve un commentaire, annoncé par des guillemets « .
mouse=a précise que la souris peut être utilisée pour placer le curseur. C’est très utile, car dans vim, on se déplace dans la ligne et non de haut en bas à travers les lignes.
number spécifie qu’on veut des numéros de lignes.
spell spécifie qu’on peut utiliser un correcteur orthographique.
t_Co=256 fait passer la console en mode 256 couleurs.
map … lie la touche F2 à une bascule qui permet de passer au ou de revenir du mode de correction orthographique.
spelllang précise évidemment la ou les langues utilisées.
hi configure la couleur du texte (rouge) d’un mot mal orthographié et de son fond (ici aucun).

Correction orthographique

Un bon article sur la correction orthographique sous vim : http://www.jdhp.org/docs/tutoriel_vim_spellfr/tutoriel_vim_spellfr.html

La correction d’un mot se fait en tapant «z=». Des propositions sont faites alors et il faut choisir l’une d’entre elle dans la liste par son numéro.

On peut corriger toutes les occurrences d’un mot avec la commande «:spellr».
On passe de faute en faute vers le bas avec «]s» et vers le haut avec «[s ».
On peut désactiver et réactiver la correction orthographique, avec «:set spell» et «:set nospell».

Éditeur de texte

Déplacements

Ici, vi et vim se confondent. Ce sont des éditeur dédié au clavier et clairement orienté vers la logique de la structure. Celle-ci fait clairement la différence entre la structure logique du texte qui fait le sens d’un paragraphe et ce que l’on voit à l’écran. Un paragraphe logique peut s’étaler sur plusieurs lignes à l’écran. À la fin de celui-ci se trouve un saut de paragraphe. Pour l’écran, il y a plusieurs saut de lignes dans ce paragraphe. Si l’éditeur de texte ne fait pas la différence entre ces sauts et un saut de paragraphe, quand vous le copierez dans un éditeur ou le texte brut est nécessaire, en HTML par exemple, le paragraphe formera plusieurs lignes et la justification sera mauvaise. De plus la numérotation ne sera pas celle des lignes logiques, c’est-à-dire celle des paragraphes, mais celle arbitraire due à la largeur de l’écran.

Cela a une grande importance pour le déplacement à l’aide des touches clavier. Pour se déplacer dans une ligne, les flèches gauche et droite ou les touches H et L respectivement permettent de se déplacer d’un caractère vers la gauche ou la droite respectivement. Entre les lignes les flèches bas et haut ou les touches J et K respectivement permettent de se déplacer d’une ligne vers le bas ou le haut respectivement.

← ou H : un caractère vers la gauche
↓ ou J : une ligne vers le bas
↑ ou K : une ligne vers le haut
→ ou L : un caractère vers la droite

Pour les déplacement dans la ligne, il faut avoir recours aux touches suivantes :

0 : curseur sur le premier caractère de la ligne
17→ ou 17L : curseur 17 caractères plus loin vers la droite
5← ou 5H : curseur 5 caractères plus loin vers la gauche
^^ : curseur sur le premier caractère de la ligne
$ : curseur sur le dernier caractère de la ligne
w : saut d’un mot vers la fin de la ligne (séparateurs de mots non alphanumériques)
b : saut d’un mot vers le début de la ligne (séparateurs de mots non alphanumériques)
W : saut d’un mot vers la fin de la ligne (séparateur de mots : espaces)
B : saut d’un mot vers le début de la ligne (séparateur de mots : espace)
( : saut vers le début de la phrase ou le début de la phrase précédente
) : saut vers le début de la phrase suivante

gg : curseur au début de la première ligne
G : curseur au début de la dernière ligne
7G : curseur au début de la 7e ligne
{ : saut vers le paragraphe précédent
} : saut vers le paragraphe suivant

H : curseur en haut de l’écran
M : curseur au milieu de l’écran
L : curseur en bas de l’écran

Viewport

Il existe beaucoup de versions de vim. Certaines sont liées à des interfaces graphiques, comme GTK par exemple. Or, la gestion d’un press-papier permettant d’échanger des éléments entre les logiciels est prise en charge par l’interface graphique. Cela signifie qu’avec une version de vim qui n’est liée à aucune interface graphique, il n’existe pas de possibilités de réaliser un simple copier-coller à l’extérieur de vim. Cela peut poser des problèmes.

Pour les contourner, il faut utiliser la notion de wiewport.

Dans vim, on peut utiliser différents wiewports. Il s’agit de scinder vim en différentes parties. Ainsi, pour scinder vim horizontalement, il suffit de lancer la commande :

:sp nom_de_fichier

Si on omet le nom de fichier, on split la fenêtre de vim en deux parties, ouvertes sur le même document. On peut ainsi travailler sur deux parties différentes du document.

Si on met un nom de fichier, on peut ouvrir deux fichier différents dans la même instance de vim. Ainsi, on peut copier coller des éléments entre ces fichiers.

On peut aussi scinder verticalement le viewport avec la commande :

:vsp nom_de_fichier

Diverses commandes existent alors pour gérer les viewports :

Ctrl w successifs : change de viewport
Ctrl w puis + : agrandit le viewport
Ctrl w puis - : réduit le viewport
Ctrl w puis = : égalise les viewport
Ctrl w puis r ou R : échange les viewports
Ctrl w puis q : ferme le wiewport

Mouvements internes

Pour copier-coller à l’intérieur du traitement de texte vim, il suffit de sélectionner une portion de texte, de placer le curseur en mode commande sur l’endroit où on veut coller et de presser le bouton du milieu de la souris.

21. Météo en ligne de commande

Dans le cas de la météo, les données à récupérer doivent forcément être sur internet. L’idée est donc « simplement » de les récupérer à l’aide d’un programme généraliste qui n’est pas spécifiquement dédié à la météo. Il s’agit de

CURL
cURL est une interface en ligne de commande, destinée à récupérer le contenu d’une ressource accessible par un réseau informatique.
Cette commande va nous permettre d’interroger un service externe, mais surtout elle offre une interface proche de la ligne de commande classique comme on va le voir. La première étape est donc d’installer cURL si ce n’est déjà fait :
apt-get install cURL
Puis, on peut immédiatement interroger la ressource wttr.in ainsi :
curl wttr.in
pour obtenir les prévision en un endroit non choisi.
À l’instar de la ligne de commande, on peut avoir accès au options disponibles pour ce service de la manière suivante :
curl wttr.in/:help
Le résultat est une magnifique aide, formellement très semblable à ce que peut fournir un logiciel en ligne de commande, qui va nous permettre de spécifier l’utilisation de la langue française et le lieux choisi :
curl -H "Accept-Language: fr" wttr.in/vannes
et le résultat est magnifique :

Relevons l’existence d’un autre service tout aussi simplement accessible, mais moins abouti graphiquement et qui fait appel à la commande finger, généralement dédiée à des informations sur l’utilisateur (essayez finger dans options), mais utilisée ici pour interroger un service externe :

finger vannes@graph.no

Quelques options sont décrites dans cet article si vous voulez l’utiliser, mais nous n’irons pas plus loin ici.

WordPress : catégorie d’accueil

Ce tout petit article pour décrire comment demander à WordPress d’afficher une catégorie d’articles en page d’accueil.

Évidemment, il ne faut pas faire afficher une page statique comme page d’accueil, mais des articles. Pour cela il faut aller dans Réglages -> Lecture et choisir « Les derniers articles ». Mais, dans ces conditions, ce sont les articles de toutes les catégories qui vont s’afficher.

Pour filtrer ceux-ci pour n’en afficher qu’une seule, il suffit d’ajouter au fichier functions.php du thème, tout à la fin :

function affiche_category($query) {
if ($query->is_home() && $query->is_main_query()) {
$query->set('category_name', 'accueil');}}
add_action('pre_get_posts', 'affiche_category');

Dans un premier temps, on y définit une fonction dont l’action sera de ne retourner que les articles de la catégorie accueil. Elle porte évidemment le nom affiche_category et reçoit une requête ($query), un article par exemple. En premier lieu, elle détermine si l’article est destiné à la page de blog de WordPress (is_home), c’est-à-dire la page principale des articles (celle-ci pourrait ne pas être la page d’accueil du site si une page statique avait été choisie pour celui-ci ; une autre fonction pourrait alors être utilisée is_front_page différence) et si la requête est principale (porte sur des articles ou page et non sur leur contenu). Si les deux conditions sont remplies, elle utilise la méthode set pour sélectionner les articles qui font partie de la catégorie dont le nom est accueil (catégorie définie préalablement par vous-même dans WordPress).

Enfin, cette fonction est déclarée comme une action à effectuer avant (pre_get_posts) la requête principale (is_main_query). Référence.

Voilà, notez que d’autres possibilités existent pour choisir une, ou plusieurs, catégories (RTFM).

19. Calendrier en ligne de commande

Ce que je voulais c’est la possibilité de mettre/retirer ou voir des événements sur mes calendriers. La recherche d’applications ne fut pas très longue, car une solution s’est imposée d’elle-même : calendar-cli. En effet, est mentionné sur la page de calendar-cli une alternative (gcalendar-cli) dont le g ne me satisfaisait pas (g ne signifiant pas Gnome, mais Goo…). De plus, la philosophie du projet calendar-cli :

The philosophy behind calendar-cli is slightly different, calendar-cli is supposed to be a simple cli-based caldav+ical client. No synchronization, no local storage.

étant simplement parfaite et le fait que celui-ci soit programmé en python m’a définitivement convaincu.

J’ai donc décidé de l’installer.

Le premier problème rencontré a été du à l’utilisation de python3. En effet, selon :

https://static.cinay.xyz/2016/05/calendar-cli-ligne-de-commande.html

il est nécessaire d’installer icalendar, caldav et tzlocal. Or, il existe phython3-icalendar, python3-caldav et python3-tzlocal dans les dépôts. J’ai donc installé tout cela et au premier lancement de calendar-cli me suis vu retourner une erreur liée à l’absence d’une méthode de tzlocal. En inspectant le fichier source, la première chose qui m’a frappé était l’appel à python2 en première ligne. J’ai donc installé python-icalendar, python-caldav et python-tzlocal et cette erreur à disparu.

On verra plus tard que la migration à python3 est en cours.

L’installation ne se fait pas via les dépôts puisqu’il n’y existe pas. Mais sur le second site mentionné ci-dessus, les instructions sont claires :

cd ~/scripts git clone https://github.com/tobixen/calendar-cli

Création d’un lien nommé calendarcmd

sudo ln -s /home/yannick/scripts/calendar-cli/calendar-cli.py /usr/local/bin/calendarcmd

Le fichier de configuration ~/.config/calendar.conf au format json

nano ~/.config/calendar.conf
{ "default": 
  { "caldav_url": "http://foo.bar.example.com/caldav/", 
    "caldav_user": "luser",
    "caldav_pass": "insecure"
  }
}

Les droits sur le fichier de configuration

chmod 0600 ~/.config/calendar.conf

Claires, parfaitement fonctionnelles, mais on en trouve une critique sur le site du projet (premier lien ci-dessus), puisqu’il est conseillé d’utiliser calendar_url pour spécifier l’adresse du calendrier spécifique d’un utilisateur et n’utiliser caldav_url que pour l’adresse du site fournissant les calendriers. Pour Framasoft, par exemple, cela donne :

{ "default":
{ "caldav_url": "https://framagenda.org/remote.php/dav/calendars/",
"calendar_url": "machin@truc.chose/personnel/",
"caldav_user": "nom_utilisateur",
"caldav_pass": "mdp"
},
"professionnel":
{ "caldav_url": "https://framagenda.org/remote.php/dav/calendars/",
"calendar_url": "machin@truc.chose/professionnel/",
"caldav_user": "nom_utilisateur",
"caldav_pass": "mdp"
}
}

Vient ensuite la phase de tests. La commande à lancer est, on l’aura compris : calendarcmd. Mais, quelle est la structure des ses arguments ? Deux exemples sont donnés. Le premier pour ajouter un événement :

calendarcmd calendar add '2016-05-18 11:45:00+2h' 'Test calendrier en ligne de commande'

Tout s’est bien passé. L’événement ajouté, s’est retrouvé comme par miracle sur mon calendrier.

Le second pour voir les événements depuis une date donnée :

calendarcmd calendar agenda --from-time=2016-05-17 --agenda-days=14

Une erreur s’est alors produite :

Traceback (most recent call last):
File "/usr/local/bin/calendarcmd", line 945, in <module>
main()
File "/usr/local/bin/calendarcmd", line 942, in main
ret = args.func(caldav_conn, args)
File "/usr/local/bin/calendarcmd", line 480, in calendar_agenda
events_ = find_calendar(caldav_conn, args).date_search(dtstart, dtend, expand=True)
TypeError: date_search() got an unexpected keyword argument 'expand'

Ici, un digression est nécessaire. La simplicité de cette erreur permettant de ne pas trop s’allonger ici, je me permet de la mettre en valeur pour montrer que l’accès au code source est indéniablement un plus dans ce genre de cas.

La lecture du retour d’erreur est claire : ligne 480 dans le code de la commande calendarcmd se trouve une erreur liée à un argument inattendu : expand. Évidemment, il faut savoir lire et prendre le temps de le faire. De plus, il faut se rappeler que la commande calendarcmd est un lien vers calendar-cli.py (voir ci-dessus). C’est donc dans ce fichier qu’il faut chercher.

À la ligne 480 se trouve :

events_ = find_calendar(caldav_conn, args).date_search(dtstart, dtend, expand=True)

et le problème vient du dernier argument de la méthode date_search de l’objet find_calendar. Évidemment, il est facile de simplement le supprimer, vu que « got an unexpected keyword argument ‘expand’ » dit clairement que python ne comprends pas celui-ci. Le problème est qu’il est parfois risqué de lancer une méthode en lui retirant un argument qui pourrait alors être par défaut différent de celui qui était donné. Enfin, par prudence, avant de le supprimer j’ai tenté de trouver la signature de la méthode (c’est-à-dire la spécification de l’ensemble des arguments qu’il utilise). Mais encore fallait-il savoir où chercher en d’autres termes, à quel module appartenait la méthode date_search où l’objet find_calendar.

À force de recherches, je suis tombé sur la documentation de caldav :

https://pythonhosted.org/caldav/caldav/objects.html#caldav.objects.Calendar.date_search

et y ai trouvé la méthode :date_search(start, end=None, compfilter=’VEVENT’) avec la description des paramètres :

  • start = datetime.today().
  • end = same as above.
  • compfilter = defaults to events only. Set to None to fetch all calendar components.

Le dernier paramètre n’étant pas expand et la valeur par défaut de compfilter étant pour récupérer tous les éléments du calendrier, supprimer le dernier argument devait être possible. Je l’ai donc fait et tout a très bien fonctionné.


Ainsi, les deux commandes de base :

calendarcmd calendar add '2016-05-18 11:45:00+2h' 'Test calendrier en ligne de commande'
calendarcmd calendar agenda --from-time=2016-05-17 --agenda-days=14

s’utilisent maintenant sans difficultés. Attention, la première va fournir en retour d’un ajout réussi, un uid d’événement (un nombre unique) qui est nécessaire pour éventuellement le supprimer (voir ci-dessous).

Pour la gestion de multiples calendriers, il suffit d’ajouter –config-section=professionnel :

calendarcmd calendar --config-section=professionnel agenda --from-time=2016-05-17 --agenda-days=14

pour obtenir les événements du calendrier professionnel. Pour en retirer :

calendarcmd calendar delete --event-uid=l_uid_de_l_evenement

Malheureusement, le retrait d’évènements par date n’est pas encore implémenté.

Pour trouver des événements et les supprimer, il faut leur uid. La commande suivante permet de les obtenir :

calendarcmd calendar --config-section=professionnel agenda --event-template "{dtstart} {summary} {uid}"

Elle retourne les événements du calendrier spécifié avec leur date de départ, le texte de commentaire et l’uid.