Un peu de libre dans ce monde propriétaire

On y parle de libre, de configuration et d'autres trucs hermétiques à la plupart des personnes

Aller au contenu | Aller au menu | Aller à la recherche

17avr.

Oripa & Ubuntu

Oripa est un outil développé en Java qui permet de concevoir des canevas de plis (ou Crease Pattern) de modèles en origami et de les plier virtuellement.

Pour le faire fonctionner, il est nécessaire d'avoir Java d'installé et plus particulièrement le Java Runtime Environment (JRE). Pour ce faire, un petit tour sur le terminal et on installe le paquet nécessaire et ses dépendances :

  1. sudo apt-get install sun-java6-jre

Puis on lance Oripa avec la commande suivante :

  1. java -jar oripaXXX.jar
  2. # où XXX est le numéro de version. 034 à la date d'écriture de ce billet

Hélas, lors du premier lancement, j'ai été confronté à l'erreur suivante :

  1. Exception in thread "main" java.lang.NoClassDefFoundError: javax/vecmath/Tuple2d
  2. at oripa.ORIPA.main(ORIPA.java:54)
  3. Caused by: java.lang.ClassNotFoundException: javax.vecmath.Tuple2d
  4. at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
  5. at java.security.AccessController.doPrivileged(Native Method)
  6. at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
  7. at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
  8. at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
  9. at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
  10. ... 1 more

Je n'avais pas vu sur la page d'Oripa que le programme nécessite l'API Java 3D. On va donc installer le paquet nécessaire :

  1. sudo apt-get install libjava3d-java

Et on relance.

Malheureusement, j'ai toujours la même erreur. Après quelques recherches, je suis tombé sur cette page qui m'a fourni des pistes pour résoudre mon problème. J'ai juste créé un lien symbolique à l'endroit nécessaire :

  1. sudo ln -s /usr/share/java/vecmath-1.5.2.jar /usr/lib/jvm/java-6-sun/jre/lib/ext/vecmath-1.5.2.jar

Et voila, ça fonctionne :)

Édition du 29 juin 2011 : La méthode proposée en faisant un lien symbolique n'est pas des plus propres. Il y a une méthode plus adaptée pour utiliser la bibliothèque vecmath. Il suffit de d'ajouter un répertoire dans la liste des répertoires lus par Java pour récupérer les bibliothèques. Donc, au lieu de lancer Oripa de la manière suivante :

  1. java -jar oripaXXX.jar
  2. # où XXX est le numéro de version. 034 à la date d'écriture de ce billet

on le lance en lui ajoutant un paramètre avec le chemin des bibliothèques :

  1. java -Djava.ext.dirs=/usr/share/java/ -jar oripaXXX.jar
  2. # où XXX est le numéro de version. 034 à la date d'écriture de ce billet

C'est plus propre, non?

11avr.

Opérations sur la hiérarchie : suite

Les précédents articles[1][2] sur le stockage et la manipulation des hiérarchies dans MySQL sont loin d'être complets. J'y apporte donc un complément avec 2 nouvelles requêtes de manipulations.
On conserve la même table et les même données que dans les articles précédents afin de rester cohérent.

Déplacer un élément

Dans l'article Un peu d'ordre dans la hiérarchie, nous avons déjà abordé le déplacement d'un élément mais juste vers un autre élément de la hiérarchie. Cette fois ci, nous allons aborder le déplacement d'un élément à la racine, c'est à dire qu'il n'aura plus de parent. Nous allons donc déplacer l'élément B vers la racine. Pour cela, il suffit de lancer ces quelques requêtes :

  1. /* Verrouillage en écriture de la table*/
  2. LOCK TABLE tree WRITE;
  3.  
  4. /* Récupération des informations de l'élément à déplacer */
  5. SELECT @nodeLeft := lft
  6. , @nodeRight := rgt
  7. , @nodeRange := rgt - lft + 1
  8. FROM tree
  9. WHERE name = 'B';
  10.  
  11. /* Récupération des informations de déplacement de l'élément */
  12. SELECT @offsetRange := MAX(rgt) - @nodeRight
  13. FROM tree;
  14.  
  15. /* Exclusion temporaire de l'élément à déplacer */
  16. UPDATE tree
  17. SET lft = -lft
  18. , rgt = -rgt
  19. WHERE lft >= @nodeLeft
  20. AND rgt <= @nodeRight;
  21.  
  22. /* Mise à jour des bornes droites des éléments concernés */
  23. UPDATE tree
  24. SET rgt = rgt - @nodeRange
  25. WHERE rgt >= @nodeRight;
  26.  
  27. /* Mise à jour des bornes gauches des éléments concernés */
  28. UPDATE tree
  29. SET lft = lft - @nodeRange
  30. WHERE lft >= @nodeRight;
  31.  
  32. /* Repositionnement de l'élément à déplacer */
  33. UPDATE tree
  34. SET lft = -lft + @offsetRange
  35. , rgt = -rgt + @offsetRange
  36. WHERE rgt < 0;
  37.  
  38. /* Suppression des verrous */
  39. UNLOCK TABLES;

Ce qui nous donne ceci :

+-----------+------+------+----+
| NAME      | LFT  | RGT  | ID |
+-----------+------+------+----+
| A         |    1 |    8 |  1 |
| ----C     |    2 |    7 |  5 |
| --------F |    3 |    4 |  6 |
| --------G |    5 |    6 |  7 |
| B         |    9 |   14 |  2 |
| ----D     |   10 |   11 |  3 |
| ----E     |   12 |   13 |  4 |
+-----------+------+------+----+
7 rows in set (0.00 sec)

Récupérer le niveau d'un élément

Utilisons la requête suivante :

  1. SELECT COUNT(p.name) - 1 AS level
  2. FROM tree p
  3. , tree n
  4. WHERE n.lft BETWEEN p.lft AND p.rgt
  5. AND n.name = 'G'
  6. GROUP BY n.id

Ce qui nous donne ceci :

+-------+
| level |
+-------+
|     2 |
+-------+
1 row in set (0.00 sec)

25fév.

Relancer un service avec cron

Dis comme ça, ça paraît simple.
Effectivement c'est très simple. Par exemple, pour relancer le service d'apache, il suffit d'ajouter la ligne suivante au cron :

  1. */1 * * * * /usr/bin/pgrep apache || /etc/init.d/apache2 start

Pour l'explication de la syntaxe, je vous laisse le soin de lire l'introduction à cron et le tutoriel de relance automatique des services.

Mais si ça avait été aussi simple dans mon cas, je n'aurais pas écrit ce message. J'ai été confronté à un problème qui m'a demandé pas mal de temps à résoudre.

Le problème était le suivant. J'avais un script de relance d'un service un peu plus complexe que celui décrit un peu plus haut. Le script fonctionnait parfaitement lancé manuellement avec l'utilisateur root. Par contre, il ne fonctionnait pas du tout quand il était lancé par cron (toujours en root).

Après de nombreux tests différents, j'ai identifié le problème. La variable PATH utilisée par cron ne contenait pas le chemin d'accès au programme appelé et ce même si l'utilisateur était le même.
Je ne sais pas si c'est dû à la configuration de Debian et d'Ubuntu [1], mais la configuration de cron [2] n'est pas prise en compte au moment de l'exécution des commandes. J'ai du ajouter manuellement le chemin d'accès dans le script.

Finalement, la solution était vraiment toute simple mais identifier le problème a été la partie la plus complexe.

Notes

[1] j'ai fait le test sur les 2 plate-formes

[2] dans le fichier /etc/crontab

15janv.

Du texte à l'image

J'avais besoin de faire une image contenant uniquement du texte. Je suis passé d'un script mal écrit, sans paramètres et absolument pas utilisable autrement que pour un unique besoin à un script un peu moins mal écrit, avec paramètres.

Si ça peut servir à d'autres qu'à moi, tant mieux. Alors voici mon code :

  1. #!/bin/bash
  2.  
  3. # Check parameters
  4. if [ $# -ne 6 ]
  5. then
  6. echo "This script need 6 parameters to run"
  7. echo "Usage: $0 file content font color bgcolor density"
  8. echo " - file: path to the output file"
  9. echo " - content: path to the file containing the content to convert into an image"
  10. echo " - font: path to the font to use"
  11. echo " - color: text color"
  12. echo " - bgcolor: background and border color"
  13. echo " - density: size of the text"
  14. exit 1
  15. fi
  16. FILE=$1
  17. if [ -e $2 ]
  18. then
  19. CONTENT=$2
  20. else
  21. echo "The content file don't exist"
  22. exit 2
  23. fi
  24. if [ -e $3 ]
  25. then
  26. FONT=$3
  27. else
  28. echo "The font file don't exist"
  29. exit 3
  30. fi
  31. COLOR=$4
  32. BACKGROUND=$5
  33. DENSITY=$6
  34. TEMP=/tmp/Temp.Text.To.Image.png
  35.  
  36. # Create the image
  37. rm $FILE
  38. while read LINE
  39. do
  40. convert -fill $COLOR -density $DENSITY -font $FONT -trim +repage -border 5 -bordercolor $BACKGROUND -background $BACKGROUND text:- $TEMP <<< $LINE
  41. if [ -e $FILE ]
  42. then
  43. montage -tile 1x2 -background $BACKGROUND -geometry +0+0 $FILE $TEMP $FILE
  44. else
  45. mv $TEMP $FILE
  46. fi
  47. done < $CONTENT
  48.  
  49. rm $TEMP

Il est également disponible en téléchargement.

19oct.

Copier des fichiers par un canal sécurisé

La semaine passée j'ai dû copier des fichiers entre plusieurs machines. J'ai fait comme d'habitude, j'ai utilisé scp de la manière suivante :

  1. scp host:fileWithoutSpaces .

Jusqu'au moment où je suis tombé sur un fichier comportant des espaces. Cette syntaxe n'était plus du tout valide car scp considère les espaces comme des séparateurs de fichiers. Dans ce cas, il faut utiliser la syntaxe suivante :

  1. scp host:"file\ with\ spaces" .

Il ne faut oublier ni les " ni les \.

En recherchant cette syntaxe, j'ai trouvé quelques petites choses intéressantes à faire avec scp. Alors en bonus :

  1. # Copier plusieurs fichiers en une seule fois :
  2. scp host:"file1 file2 file3" .
  3.  
  4. # Copier un répertoire complet :
  5. scp -r host:folder .
  6.  
  7. # Copier plusieurs fichiers vers une machine distante
  8. scp file1 file2 file3 host:.
  9.  
  10. # Copier un fichier avec espaces vers une machine distante
  11. scp file\ with\ spaces host:.
  12. # ou
  13. scp "file with spaces" host:.

- page 1 de 2