Catégorie : shell

Gimp, scripting et Python-fu : exemple par la transformation d’une image PNG en image transparente

J’ai été plus loin dans l’automatisation de Gimp.

J’ai voulu reprendre mes deux articles qui parlaient de Script-fu : le premier pour débuter ici, et le second qui passe à peine à la vitesse supérieure, qui explique l’assignation des variables ici.

Mais comme je suis un grand fan de Python et que tout a été fait pour pousser Python en avant dans Gimp, j’en ai profité.
Trois heures de travail avant d’y arriver.

Première chose à savoir :

On parle de script Python, mais ce sont des plugins.
Donc, lorsqu’on les installe, il faut les mettre dans le répertoire ~/.gimp/plug-ins/ et non pas ~/.gimp/scripts/.

Deuxième chose :

Ils doivent être exécutables. Donc :

chmod +x ~/.gimp/plug-ins/monscript.py

Troisième chose :

Enfin, allez chercher des exemples ici : http://registry.gimp.org/

Vous les installez et vous les lancez à partir de là vous avez tout ce qu’il vous faut.
Si vous avez lu ces trois informations avant de vous lancez dans l’aventure je vous aurais probablement fait gagner au moins une demi-journée.

Enfin, pour que la ligne de commande fonctionne sur les dernières versions de Gimp (2.6.8) à l’heure de l’écriture de cet article, il y a plein d’articles obsolètes sur le net. Je vais encore vous faire gagner des heures de recherche :

Voici un exemple complet d’un lancement en ligne de commande qui fonctionne :

gimp -i --batch '(python-fu-batch-to-transparent-indexed RUN-NONINTERACTIVE "/home/olivier/Bureau/france.php.png" "/home/olivier/Bureau/france.2.php.png")' -b '(gimp-quit 0)'

Et voici mon plugin tout simple que j’ai codé en 15 minutes, mais avant d’arriver là j’ai cherché pendant six heures…

Cliquez ici pour le télécharger.

Ce plugin transforme une image PNG en la même image, mais en transparente et en couleurs indexée.
Il n’est pas 100% terminé, car la couleur de transparence est codée en dur, mais il fonctionne très bien pour peu que votre couleur soit le blanc 🙂

Pour ce qui est de la méthode, je me suis très fortement inspiré de ce site.

Si je vous ai aidé n’hésitez pas à me laisser un message !

scp : comment résoudre le problème C0644

Il arrive parfois que lorsqu’on fait un scp, ça ne fonctionne pas, et on peut lire quelque chose comme :

>> scp root@olivierpons.fr:/var/www/html/pysoko.tar.bz2 .
root@olivierpons.fr's password:
C0644 129502 pysoko.tar.bz2
>>

Dans cet exemple, je veux récupérer le fichier :
pysoko.tar.bz2
qui est sur le PC distant dans le répertoire
/var/www/html/
sachant que le PC distant est nommé :
olivierpons.fr.
En fait le problème est super simple : lorsque le programme scp se connecte pour faire la copie, un shell du distant nommé olivierpons.fr est ouvert, et par conséquent tout ce qu’il y a dans la configuration du shell est exécuté, donc tout ce qu’il y a dans le fichier de configuration du shell .bashrc.
Pour faire simple, si vous avez fait un « echo » quelque part dans le fichier de configuration du shell .bashrc, changez le par tty -s && echo ".
L’explication est dans ce site génial, qui explique tout sur le SCP, encore mieux que mon article, qui sort pourtant numéro un sur google France lorsqu’on tape scp linux

Le monde est injuste !

shell : remplacer un retour chariot par un espace

Super facile : l’outil tr.
Exemple concret : je veux lister les fichiers d’un répertoire et tous les passer à vim, par exemple pour y appliquer une macro.

Je les liste à la main du genre :

~/ # find ws -type f
ws/jsDecision.php
ws/jsDossierDocuments.php
ws/jsInfosEmprunt.php
ws/jsInternetDocumentDossierEditer.php
ws/jsListeFormulesGaranties.php
ws/jsLogin.php

Il suffit d’ajouter | tr '\r\n' ' ' (qui signifie « transforme tous les retours chariots en espaces ») :

~/ # find ws -type f | tr '\r\n' ' '
ws/jsDecision.php ws/jsDossierDocuments.php ws/jsInfosEmprunt.php ws/jsInternetDocumentDossierEditer.php ws/jsListeFormulesGaranties.php ws/jsLogin.php

vim : l'efficacité par la preuve directe

Depuis que j’ai vu ces vidéos, je sors avec plein de femmes, j’ai plein d’argent, et je suis aimé de la France entière.

Si vous parlez couramment l’Anglais, il faut absolument que vous voyez les vidéos de ce qu’il est possible de faire avec vim et qu’on n’a pas forcément en tête.

http://vimcasts.org/

Laissez d’autre sites en commentaire si vous avez des liens intéressants. Je n’hésiterai pas à les valider !

vim : expressions régulières rechercher remplacer (mémo)

Ci-suit une série d’expressions régulières qui fonctionnent sous vim, et dont j’ai fait la traduction en langue Française, afin que vous puissiez comprendre les subtilités :

  • /^ \+$ : rechercher toutes les lignes qui commencent et finissent par une suite de minimum un ou plus d’espaces (un antislash avant le « + »)
  • /^ *$ : rechercher toutes les lignes qui commencent et finissent par une suite de minimum zéro ou plus d’espaces (pas d’antislash avant le « * »)
  • /^ \*$ : rechercher toutes les lignes qui commencent par un espace et finissent par le caractère « * » (un antislash avant le « * »)
  • /^ \{1,1\}$ : rechercher toutes les lignes qui contiennent un et un seul espace (ne pas oublier l’antislash avant les « {} »)

Et maintenant une expression complexe qui m’a été très utile :
Si vous tapez exactement cela :

:%s/\($this->[a-z]\+\)\(_\)\(.\)/\1\u\3/g

Vous aurez tous les ordres du type :

$this->Sejour_deb

Qui seront transformés en :

$this->SejourDeb

Très très utile.
Explication :

:%s/\($this->[a-z]\+\)\(_\)\(.\)/\1\u\3/g
: = exécuter un ordre ;
% = appliquer sur la totalité du document ;
s = appliquer sur la chaine (ici ligne par ligne) ;
\($this->[a-z]\+\) = groupe qui a $this-> puis une série de lettres ;
\(_\) = groupe qui a un tiret bas ;
\(.\) = groupe qui contient un caractère quel qu’il soit ;
On voit qu’il y a trois groupes, ils sont accessibles via antislash puis le numéro du groupe, exemple : »\1« , et le cas concret :
/ = remplacer par… ;

  • \1 le groupe numéro 1 ;
  • \u mettre en majuscule ;
  • \3 le groupe numéro 3 ;

/g faire toutes les occurrences trouvées.

Shell et tilde avec 'home' ou 'end' : la solution

Le solution a été trouvée ici.
Je vous la traduis en Français :
Il vous faut créer un fichier nommé .inputrc dans votre répertoire personnel, puis y ajouter les lignes suivantes :
set meta-flag on
set input-meta on
set convert-meta off
set output-meta on


"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert
"\e[5C": forward-word
"\e[5D": backward-word

Linux : astuces bashrc

Lorsqu’on lance un nouveau shell sous Linux, il exécute un fichier ~/.bashrc.
Dans ce fichier, on peut y mettre des choses intéressantes, notamment :

export HISTCONTROL=erasedups
export HISTSIZE=10000
shopt -s histappend

Cela signifie :

  • effacer les lignes de commande en double ;
  • se souvenir au plus de 10000 lignes de commande (on n’en a jamais assez en fait) ;
  • dire au shell d’ajouter tout cela au fichier historique existant (et non pas ré-écrire par dessus (ce qui est fait par défaut)).

Programmer en C la librairie gd : le texte

J’ai décidé de faire un petit article qui explique rapidement comment écrire du texte « non crénelé », donc « antialiasé » du des images, en C, en utilisant la librairie gd.

Tout est très simple : vous trouverez déjà le manuel ici, pas mis à jour mais suffisant et les exemples fonctionnent, ce qui est le plus important.

Ce qui m’a posé le plus de problème, ce n’est pas de demander à écrire du texte. L’exemple ici fonctionne parfaitement, faites un copier coller, hop on y est.
Non, le problème c’est la « région » calculée dans laquelle sera dessiné le texte.
Pour résumer, on demande de pré-calculer la « boîte » dans laquelle sera dessiné le texte (toujours l’exemple ici).
Ce que j’ai mis beaucoup de temps à comprendre, c’est ce que je vais traduire dans « mon » langage : la boîte englobante qui est renvoyée, c’est l’espace qui sera utilisé en fonction du point de référence (x,y) que vous donnez pour dessiner.

Je m’explique. Vous demandez à calculer la boite pour dessiner le texte en passant la variable NULL :

err = gdImageStringFT(NULL,&brect[0],0,f,sz,0.,0,0,s);
if (err) {fprintf(stderr,err); return 1;}

Maintenant, dans brect il y aura ce genre d’informations :


     (   -1,  -57)     ( 1513,  -57)
           +-----------------+
           |                 |
           |                 |
           +-----------------+
     (   -1,   15)     ( 1513,   15)

Et en fait, c’est uniquement des informations pour vous, parce qu’après, lorsque vous lui demanderez de dessiner, il les ignorera : seules les informations x et y seront utilisées :

err = gdImageStringFT(im,&brect[0],black,f,sz,0.0,x,y,s);
if (err) {fprintf(stderr,err); return 1;}

Autrement dit, prenons un exemple : vous voulez dessiner votre texte en x=0. Seulement, le rectangle de retour est celui que j’ai affiché en haut : ça signifie que le dessin va « déborder » de (-1) pixel sur x. Autrement dit, si vous voulez le mettre en 0, il faut donner les coordonnées (x=1). Même chose pour y : les lettres vont « s’étaler » 57 pixels au dessus, et 15 pixels en dessous. Donc si vous voulez écrire le texte en (0,0), il vous faudra passer x=1, y=57.

En relisant ça parait facile, mais ça ne l’a pas été pour moi !
En espérant que cela serve à quelqu’un un jour…

Linux : exemple php pratique pour grep, awk, sort, uniq et xargs

Ci-suivent quelques étapes qui expliquent l’utilisation des outils grep, awk, sort et uniq. C’est juste un exemple concret et pratique, n’imaginez pas un truc immense ! J’espère que cela vous donnera des idées, si un jour vous avez besoin de faire quelque chose dans le genre.

Objectif : lister tous les fichiers php du répertoire courant, qui font appel à l’ordre « date() ».

Donc :

  • Ordre « find » de Linux qui liste tous les fichiers d’un répertoire et de ses sous-répertoires :
    >find .
    ./robots.txt
    ./tarification2.php
    ./partenaire_demande.php
    ./img
    ./img/menu-gb_02-Carte-image_02_o.gif
    ./img/fleche_blc_fond_bleu.gif
    ./img/old_get_adobe_reader.gif
    ./img/menu-gb_02-Carte-image_05_o.gif
    ./img/ste_gestion_over.gif
    ./img/cbp_attest_ass_over.gif
    ./img/index_06.jpg
    [etc. etc.]
  • Ordre « grep » de Linux qui ne prend que les fichiers « qui se terminent par php » :
    >find . | grep php$
    ./img/index.php
    ./aore/verlogin.php
    ./aore/tarication2.php
    ./aore/img/iex.php
    ./aore/corats.php
    ./aore/ind.php
    ./aore/ccts.php
    [etc. etc.]
  • Ordre « xargs » de Linux qui dit « je vais te donner un programme (ici « grep »), et tu lui fais suivre ligne par ligne les résultats. Pour la note, « grep 'date(' [nom_de_fichier] » vérifie si dans le fichier [nom_de_fichier], il y a ‘date(‘ :
    >find . | grep php$ | xargs grep 'date('
    ./pe.php: $date=date("Y-m-d H:i:s");
    ./partde.php: $date_french=date("d-m-Y H:i:s");
    ./as/vergin.php:$date=date("Y-m-d H:i:s");
    ./as/cs.php:$date=date("Y-m-d H:i:s");
    ./as/cs.php:$date=date("Y-m-d H:i:s");
    ./as/cs.php: $date=date("d-m-Y H:i:s");
    ./as/sis.php:$date=date("Y-m-d H:i:s");
    ./ae/sis.php:$date=date("Y-m-d H:i:s");
    ./ae/stre_cle.php:$date_heure = date("Y-m-d H:i:s");
    ./ae/stre_cle.php:$date = date("Y-m-d");
    [etc. etc.]
  • Ordre « awk » qui prend la ligne en cours, considère que les « : » sont les séparateurs (-F:), et n’affiche en sortie que le premier enregistrement ('{print $1}') pour chaque ligne :
    >find . | grep php$ | xargs grep 'date(' | awk -F: '{print $1}'
    ./re/vein.php
    ./re/ctrs.php
    ./re/ctrs.php
    ./re/ctts.php
    ./re/sises.php
    ./re/sires.php
    ./re/sire_cle.php
    ./re/sire_cle.php
    ./re/sire_cle.php
    ./re/sire_cle.php
    ./ae/mu.php
    ./ae/mu.php
    [etc. etc.]
  • Ordre « uniq » qui prend la totalité de ce qu’on lui passe, et supprime les doublons :
    >find . | grep php$ | xargs grep 'date(' | awk -F: '{print $1}' | uniq
    ./re/vein.php
    ./re/ctrs.php
    ./re/ctts.php
    ./re/sises.php
    ./re/sires.php
    ./re/sire_cle.php
    ./ae/mu.php
    [etc. etc.]
  • Ordre « sort » qui trie par ordre alphabétique :
    >find . | grep php$ | xargs grep 'date(' | awk -F: '{print $1}' | uniq | sort
    ./ae/mu.php
    ./re/ctrs.php
    ./re/ctts.php
    ./re/sises.php
    ./re/sires.php
    ./re/sire_cle.php
    ./re/vein.php
    [etc. etc.]

Et voilà ! Une minute pour taper cette commande, et on a la liste de tous les fichiers à vérifier pour être certain qu’il n’y aura plus de warnings() lors de l’utilisation de date() dans ces fichiers php.
Pour la note, j’ai eu besoin de faire ça parce que ces fichiers devaient avoir en tête l’initialisation préalable date_default_timezone_set(). Ces fichiers sont les fichiers d’un très vieux site qu’il faut faire fonctionner en mettant au minimum les mains dedans, c’est ce que j’ai tenté de faire (pour préserver aussi ma santé mentale).

(Update 6 février 2011)
Sur ce site ici qui me cite, il y a une réponse très intéressante : lorsqu’on connait bien l’ordre « find« , on peut résumer tout mon article en une seule ligne et un seul ordre :

find -iname "*.php" -exec grep "\Wdate(" "{}" \; -print

Bon, le résultat ne renvoie pas que les fichiers, mais il est bien formaté, c’est aussi très pratique. Voici un exemple de sortie de cet ordre :

  $debloc_jj = (int) date('d');
  $debloc_mm = (int) date('m');
  $debloc_aa = (int) date('Y');
  echo '<li>Lancement des calculs à '.date("H:i:s").'.</li>';
  echo '<li>Terminé à '.date("H:i:s").'.</li>';
./_tests_unitaires/tarifs_generali/tarifs_2010.php
  $debloc_jj = (int) date('d');
  $debloc_mm = (int) date('m');
  $debloc_aa = (int) date('Y');
./_tests_unitaires/verifs.php
  $debloc_jj = (int) date('d');
  $debloc_mm = (int) date('m');
  $debloc_aa = (int) date('Y');
./_tests_unitaires/verifs_multi.php

Vim : aide et exemples excellents

Voici un site qui, si vous parlez Anglais, va vous faire gagner un temps fou :
http://vimcasts.org/
Ce sont des vidéos explicatives sur le fonctionnement de vim, avec toutes les options et surtout, pourquoi vim vous fait gagner du temps.

Ici aussi, si vous parlez Anglais, ce document explique pour les développeurs, comment gagner un temps fou avec vim.