Thursday, February 12, 2009

Script powaa!

Bon. Ouvrez un p'tit terminal (tcsh), on va s'amuser ...

display fairy.jpg
setenv FAIRY `eesh -ewait window_list | grep Magick | cut -f 1 -d :`
randomize `find /pingu/photos/ | grep -v thumb` |\
fe - "display -window $FAIRY '%' & sleep 8"
C'est ma manière à moi de me faire un petit diaporama de mes photos sur mon laptop, mode "discret: je travaille mais j'ai besoin de voir un peu mes proches".

J'vous explique ? Bon, tout d'abord, vous devez penser à tous ces programmes comme des "filtres" qui reçoivent des données par un côté (l'entrée standard) et qui en produisent de l'autre côté (la sortie standard). Un élément de base pour interconnecter les programmes est le tube ("unix pipe") représenté par la barre verticale. program1 | program2 attache les deux programmes de sorte que la sortie de program1 est utilisé comme entrée pour program2... Visualisez une usine avec des robots qui bricolent des pièces qui défilent sur un tapis roulant et vous n'êtes pas loin.

Comme certains programmes ne sont pas prévus pour recevoir leurs données sur l'entrée standard mais plutôt comme des arguments sur la ligne de commande, j'utilise aussi les guillemets arrière qui remplace dans une commande une expression par le résultat de son évaluation. Si add et mul étaient des programmes pour additioner et multiplier leurs arguments, on pourrait faire des expressions un peu plus compliquées à coup de add 5 `mul 2 3` qui serait transformé en add 5 6 avant d'appeler le programme add.

I love how scripting expands the possibilities of programming. Maybe I could have experienced something similar with Visual Basic, but that tool has never happened to be available on my Windows systems afaik. The code you see above is a script I use to periodically change one part of my screen's background as if it was a diaporama.

display FILE will just create the window and show one file. then the line with eesh will capture the identifier of that window into some variable and calling display again with -window $FAIRY will make it paint on the existing window instead of creating a new one.

That's already pretty neat, but I can push it further, like scanning through my pictures repository with find, filtering out the thumbnails with grep and randomize the output with a Perl script of mine that isn't even aware it is processing picture file names.

This is possible thanks to the unix pipe | and shell sub-expressions `sub expr` that gets a program called and its output injected as parameter for another program.

Bref, les programmes utilisés ici:
  • display, le programme d'affichage du projet ImageMagick hyper-standard. Par défaut il ouvre une nouvelle fenêtre pour la nouvelle photo, mais avec -window , il modifie l'image de fond d'une fenêtre existante. En l'occurence, cela me changera l'image affichée.
  • eesh, le kit du bricoleur pour enlightenment, utilisé ici pour récupérer la liste des fenêtres. Si vous n'utilisez pas enlightenment, le package wmctrl pourrait faire l'affaire ...
  • grep, le filtre passe partout, en standard dans toutes les distributions Unix, utilisé aussi bien pour retrouver la fenêtre dont le titre contient "Magick" dans la deuxième commande que pour retirer toutes les miniatures dans la deuxième commande
  • find, également un outil standard, liste tous les fichiers à partir d'un répertoire donné
  • cut : pour extraire un champ d'une ligne du type "fichier CSV".
  • setenv <var> <val>: pour donner un nom au résultat d'une exécution (en l'occurence, enregistrer le n° de la fenêtre d'affichage dans la variable $FAIRY)
  • randomize <args> : un p'tit script perl à moi qui renvoie ses arguments mélangés, ligne par ligne.
  • fe - "commande" : un autre petit programme à moi ("foreach") qui applique une commande à une liste d'arguments. Les puristes auraient utilisé xargs ou find -exec.
  • sleep <secondes> : pour marquer une pause entre 2 images, bien-sûr
Chouettos, non ? Allez, les amateurs de VBA. Vous mettez combien de temps pour faire ça ?

4 comments:

PypeBros said...

j'ai du remanier un peu la chose, et intégrer la fonctionnalité "randomize" dans le programme "foreach" (fe) : "randomize" ne comprenait pas la différence entre les espaces qui séparent les mots des espaces qui séparent les éléments. J'aurais probablement pu jouer avec find -print "\t%h/%f", aussi.

sylvainulg said...

fe -random "mv /tmp/thisphoto.jpg /tmp/lastphoto.jpg ; ln -s '%' /tmp/thisphoto.jpg ; what-is-love ; display -window $FAIRY '%' ; sleep 15"

et je rajoute un bouton "Fancy Launcher" qui appelle "love-it, forget-it, show-again, hold-it et next-one" selon le bouton avec lequel il est cliqué...

Anonymous said...

PS: si au lieu de la technique "display", on souhaite utiliser un des économiseurs d'écran (p.ex. glslideshow ou carousel), ceux-ci utilisent xscreensaver-getimage-file --name <répertoire> pour choisir quelle image afficher. On peut "bricoler" autour de cet exécutable p.ex. pour qu'il crèe lui aussi les liens "thisphoto et "lastphoto" utilisés pour promouvoir ou éliminer les images via FancyLauncher.

PypeBros said...

et pour ceux qui n'ont pas Enlightenment, eesh peut être remplacé par un coup de xwininfo, manuellement.