Le but

Si vous avez tendance à tapisser les bords de votre écran avec des petits papiers (généralement jaunes) pour vous rappeler tout ce que vous avez à faire, ou que vous faites confiance à votre mémoire, parfois vacillante, voici peut-être une solution. Loin de l'utilisation d'un logiciel de type agenda (comme « Mozilla Calendar ») nous allons vous proposer un petit script qui vous affichera une simple boîte de dialogue au moment où vous aurez choisi de vous faire prévenir.

Les ingrédients

  • Xdialog, outil permettant l'affichage de boîtes de dialogues diverses et variées de manière très simple
  • at, planificateur de tâches, à comparer avec cron
  • Bash, le shell

Les principes

L'idée est toute simple : demander à notre système préféré de nous afficher un message à un moment précis pour nous rappeler, par exemple, un rendez-vous important, une émission de radio à ne pas oublier, sortir le chien, etc. Ce message sera affiché dans une boîte de dialogue grâce à Xdialog.

Pour déclencher l'affichage de cette boîte de dialogue, nous avons choisi l'outil at, souvent comparé à cron, mais dont la finalité diffère légèrement. cron est utilisé pour des tâches régulières, répétées. Exemples : tous les jours à 6h du matin, tous les week-end, toutes les minutes, etc. at planifie une tâche à exécution unique. Une fois accomplie, elle est effacée de la liste. at présente également plus de souplesse dans la déclaration des événements. Ainsi, l'on pourra planifier une tâche pour le 7 juillet 2004 à 10h45, ou encore pour dans un mois, deux jours et six heures à partir de maintenant. Dans notre script, nous allons utiliser les deux approches.

Pour la saisie des pense-bêtes nous proposons également l'utilisation de Xdialog et l'affichage successif de trois boîtes de dialogue : la première vous demande le texte à rappeler. La seconde est une boîte de type calendrier vous permettant de choisir facilement la date. Enfin la troisième vous demande l'heure avec une boîte adaptée.

La pratique

Nous supposons que vous savez manipuler Xdialog. Si ce n'est pas le cas, reportez-vous à l'article d'introduction, dans ce même magazine. Ici, nous allons utiliser systématiquement deux options (ligne 5) :

  • -stdout redirige les données produites par Xdialog sur la sortie standard, ainsi l'on pourra les récupérer dans une variable ;
  • -title Pense-bête pour l'esthétique, cela permet de personnaliser la fenêtre en y adjoignant un titre.

Posez le décor

Chaque pense-bête sera dirigé par un script que nous allons créer à la volée lors de l'enregistrement. C'est ensuite ce script qui sera appelé en temps voulus pour afficher la boîte de dialogue de rappel.

Nous avons besoin d'un point de stockage pour tous les scripts qui correspondent à tous les pense-bêtes que vous aurez besoin de créer. Nous choisissons pour cela le répertoire .pensebete situé à la racine de votre répertoire personnel et nous définissons la variable pensebetedir (ligne 4).

Lors de la création d'un nouveau pense-bête, nous devons vérifier systématiquement que le répertoire existe bien. C'est ce que nous faisons à la ligne 8: le test -d vérifie l'existence du répertoire $pensebetedir. Si le test échoue, la commande mkdir est exécutée.

Récupérez les données

Attaquons la partie qui sera visible à l'utilisation : la saisie du pense-bête au moyen des boîtes de dialogue successives. Pour chaque boîte nous récupérons le résultat dans une variable différente. Ainsi, $message est renseigné par une inputbox (boîte simple de saisie de texte) et contient le texte de votre pense-bête. $date renferme la date d'exécution au format jj/mm/aaaa (par exemple 17/05/2004) : c'est une boîte calendrier qui permet de renseigner cette variable simplement. Enfin, $heure contient l'heure de rappel au format hh:mm:ss (exemple : 13:22:32).

Tout cela se passe aux lignes 11 à 13. La syntaxe $(commande) permet de récupérer le résultat de commande envoyé sur la sortie standard. Vous remarquerez également les symboles && et || en fin de lignes. Ils permettent de créer un lien entre les commandes en fonction du résultat d'exécution de la précédente. Ainsi, dans la syntaxe cmd1 && cmd2, cmd2 sera exécutée seulement si cmd1 s'achève avec succès. Si cmd1 échoue, alors cmd2 est ignorée. À l'inverse, +cmd1 || cmd2+ signifie que cmd2 sera appelée en cas d'échec de cmd1.

Ici, cela se traduit par le fait que l'on affiche une nouvelle boîte de dialogue uniquement si l'on a bien validé la précédente. En cas d'échec de l'une des boîtes de dialogue, les autres sont ignorées et l'on passe directement à la ligne 14, provoquant ainsi une sortie brutale du programme. Notez que le code de sortie 0 signifie une fin normale : tout autre code indique une erreur.

Traitez les données

Les données de date et d'heure récupérées précédemment ne sont pas au bon format pour la commande at. La date doit être au format anglais (mm/jj/aaaa) et l'heure ne doit pas contenir les secondes. Nous allons donc procéder à quelques réajustements.

La date tout d'abord. À la ligne 17 nous recomposons la date en découpant la variable $date en trois morceaux que nous recollons ensuite dans un ordre différent. Par exemple, la syntaxe ${date:3:3} permet d'extraire de la variable $date trois caractères à partir du numéro 3 (n'oubliez pas que le premier porte le numéro 0). Cela correspond donc au mois suivi du caractère slash de séparation.

Pour l'heure, c'est plus simple. Il suffit juste de retirer le dernier deux-points et tout ce qui suit. C'est exactement ce que nous faisons à la ligne 18. La syntaxe ${variable%motif} permet de retirer la plus petite occurrence de motif située dans la partie finale de variable. Notre motif, ici, est :* qui correspond à un deux-points suivi de n'importe quels caractères.

Créez un nouveau script

Pour déclencher nos pense-bêtes, nous avons besoin d'un script pour chacun qui sera exécuté par at au moment voulu. Cependant, ce n'est pas vous qui allez rédiger ces scripts, mais cela sera automatisé ; c'est d'ailleurs le but de ce cas pratique.

Entre les lignes 22 à 28 de notre présent script nous avons le squelette des scripts créés à la volée. Nous reviendrons ensuite sur le contenu de ce squelette. Pour l'instant, intéressons-nous à la façon dont le script est créé.

Tout d'abord, le nom. Afin de garantir l'unicité de ce dernier, nous choisissons d'utiliser le nombre de secondes écoulées depuis le 1er janvier 1970 à minuit. Cela peut paraître étrange comme choix, mais cette donnée s'obtient simplement par la commande date +%s et donne un nombre différent toutes les secondes. À la ligne 21 nous définissons une variable composée de ce nombre (qui du coup est considéré comme un nom de fichier) et du chemin absolu vers le futur fichier de script.

Ensuite, la rédaction du script. La ligne 22 indique que nous allons écrire (commande cat) vers le fichier $pensebetename (créé à la volée) toutes les lignes qui suivent jusqu'à trouver l'étiquette « FIN ».

Le script de rappel

Détaillons maintenant ce script de rappel. Nous voulons proposer la possibilité de se faire rappeler le même pense-bête un peu plus tard (par exemple dix minutes plus tard). Nous utilisons donc une boîte à deux boutons (yesno). Le bouton « Oui » correspond à l'acceptation de la notification. Le bouton « Non » induira la reconduction du pense-bête pour dix minutes supplémentaires. Comme la dénomination « Non » n'est pas des plus explicite pour une telle action, nous allons modifier le texte de ce bouton : -cancel-label "Rappel 10 min".

Si vous avez essayé de tester la boîte yesno, vous aurez sûrement constaté qu'elle ne renvoie rien sur la sortie standard. En fait, il faut tester le code de succès de l'application : de suite après avoir quitté la boîte de dialogue, testez la valeur de la variable $?. Si vous avez pressé « Oui », $? vaut 0. Si vous avez pressé « Non » (ou toute autre dénomination, seul le bouton importe), le résultat sera 1.

Nous testons donc cette valeur à la ligne 24. Le signe dollar est précédé d'un anti-slash, car, lors de l'écriture du fichier il ne doit pas être interprété comme c'est le cas pour $message ou $dlg_cmd. Il doit être écrit tel quel, donc il faut le protéger. Si $? vaut 1, alors nous reconduisons l'exécution de ce script pour dans dix minutes à partir de maintenant (now + 10 min). Sinon, nous pouvons effacer le script.

Programmez l'appel

Détaillons à présent la commande at. Elle est employée par deux fois aux lignes 25 et 31. La syntaxe est très simple : soit vous précisez une heure et une date précise (ligne 31), soit vous donnez un décalage par rapport à une date précise (l'instant présent étant désigné par le mot-clé now) comme à la ligne 25.

L'option -f permet de préciser un nom de script à exécuter le moment venu.

Le source

[bash]
 1 #!/bin/bash
 2 
 3 # Variables locales
 4 pensebetedir=$HOME/.pensebete
 5 dlg_cmd='Xdialog --stdout --title Pense-bête'
 6 
 7 # Vérification de l'existence du répertoire des pense-bêtes
 8 [ -d $pensebetedir ] || mkdir $pensebetedir
 9 
10 # Récupération des données auprès de l'utilisateur
11 message=$($dlg_cmd --inputbox "Entrez votre pense-bête" 0 0) &&
12 date=$($dlg_cmd --calendar "Entrez la date de rappel" 0 0 0 0 0) &&
13 heure=$($dlg_cmd --timebox "Entrez l'heure de rappel" 0 0) ||
14 exit 1
15 
16 # Aménagement des données pour at
17 date=${date:3:3}${date:0:3}${date:6}
18 heure=${heure%:*}
19 
20 # Création du script qui sera appelé par at
21 pensebetename=$pensebetedir/$(date +%s)
22 cat >>$pensebetename << FIN
23 $dlg_cmd --cancel-label "Rappel 10 min" --display ":0" --yesno "$message" 0 0
24 if [ \$? == 1 ]
25 then at -f $pensebetename now + 10 min 
26 else rm $pensebetename
27 fi
28 FIN
29 
30 # Enregistrement auprès de at
31 at -f $pensebetename $heure $date

Exemple

Executez le script :

pensbet

Puis renseignez le message :

le jour

et l'heure où ce message devra apparaître sur votre écran

Le script généré sera celui-ci :

[bash]
Xdialog --stdout --title Pense-bête --cancel-label "Rappel 10 min" --display ":0" --yesno "Acheter du pain et du fromage" 0 0
if [ $? == 1 ]
then at -f /home/bdc/.pensebete/1084811787 now + 10 min 
else rm /home/bdc/.pensebete/1084811787
fi

Et il produira cette fenêtre le moment venu :

Documentation

  • man Xdialog, man at, man bash
  • syntaxe des éléments temporels pour at : consultez le fichier /usr/share/doc/at/timespec
  • Xdialog