Fedora-Fr - Communauté francophone Fedora - Linux

Planet de Fedora-Fr : la communauté francophone autour de la distribution Linux Fedora

A propos

Cette page est actualisée toutes les heures.

Cette page est une sélection de blogs autour de Fedora. Fedora-Fr.org décline toute responsabilité au sujet des propos tenus par les auteurs des blogs de ce planet. Leurs propos sont leur entière responsabilité.

Le contenu de ce planet appartient à leurs auteurs respectifs. Merci de consulter leur blogs pour obtenir les licences respectives.

Mot-clefs : Développement

Dêpôt expérimental Fedora 16

Remi Collet

Je travaille souvent sur des fonctionnalités afin de préparer des mises à jour, réaliser des tests, etc.

J'ai donc décidé de mettre ces RPM à votre disposition, uniquement pour fedora 16 x86_64, que j'utilise comme système principal.

Voir : Dépôt remi développement Actuellement on y trouve httpd 2.4.1 et php 5.4.0 (rétro-portage des versions Fedora 18). Bien sûr, son utilisation est vraiment réservé aux experts qui n'ont pas peur de casser leur machine. Pour yum, il suffit d'ajouter dans le fichier /etc/yum.repos.d/remi.repo : [remi-dev]name=Les RPM de remi en DEV pour... Lire Dêpôt expérimental Fedora 16

PHP 5.4 serveur de développement

Remi Collet

Désormais, PHP fournit un petit serveur web de développement permettant de faire fonctionner rapidement une application.

Pour le lancer, il suffit de lui indiquer l'adresse d'écoute et le répertoire racine des pages, exemple $ php -S 127.0.0.1:8080 -t /work/GLPI/0.83-bugfixesPHP 5.4.0RC4-dev Development Server started at Sat Dec 17 09:39:11 2011Listening on 127.0.0.1:8080Document root is /var/www/htmlPress Ctrl-C to quit.Ensuite, depuis le navigateur :... Lire PHP 5.4 serveur de développement

GLPI 0.83 : les groupes

Remi Collet

La prochaine version 0.83 de GLPI est actuellement en période de béta-test.

Gros plan sur une des évolutions de cette version.

La notion de "groupe" dans GLPI est très importante car elle permet d'organiser l'activité : classement des machines, représentation de l'organigramme de l'entreprise, organisation du support par domaine compétence, etc. Plusieurs évolutions régulièrement demandées on été réalisées pour la version 0.83.   1. Arborescence Désormais, les groupes... Lire GLPI 0.83 : les groupes

FluxSphinx, l'intégration de Sphinx dans FluxBB

Guillaume Kulakowski

Il y a de cela quelques mois, nous avons rencontré des montées en charge sur Borsalino (l'ancien serveur de Fedora-Fr). Après enquête, il s'est avéré que la recherche de certains mots (ceux qui remontaient le plus de résultats) sur les forums faisait planter les sites en entrainant une charge sur le serveur MySQL. La sentence est vite tombée et nous avons été contraints de couper la recherche native sur les forums de Fedora-Fr et de basculer sur Google Custom Search Engine.

Avec l'arrivée de Stetson, le nouveau serveur mis à disposition par nos amis d'Ikoula, la question de remettre la recherche en place s'est posée. Cependant, je trouvais frustrant de répondre à un problème de conception (la recherche native de FluxBB bien que très efficace n'est pas adaptée aux grosses volumétries) par une course à l'armement (la RAM dans notre cas). Bref, je travaillais depuis quelques temps à limplémentation de Sphinx pour FluxBB sous le nom de code FluxSphinx. Et depuis ce long week-end de Toussaint, FluxSphinx est en production sur les forums de Fedora-Fr et le code est disponible sur le site du projet.

A noter que la configuration permet d'inclure la librairie PECL compilée plus efficiente que l'API en php (que vous pouvez également utiliser).

Pour le moment FluxSphinx est Iso fonctionnel avec la recherche native de FluxBB, seul le tri par pertinence ainsi que le récapitulatif dans le résultat de la recherche le distingue de la recherche native.

Cette version 0.9 donnera naissance rapidement à une v1.0 lorsque les bugs éventuels auront été remontés et corrigés. Ensuite devrait arriver une version 1.1 avec l'arrivée de facettes.

Publication de Gauffr 0.9

Guillaume Kulakowski

Après pas mal de travail, la version 0.9 de Gauffr vient de voir le jour. Cette version préfigure à peu de chose près ce que sera la version 1.0 une fois que les derniers ajustements seront réalisés.

Ecran de connection de Gauffr

Pour énième rappel, Gauffr est un système permettant de connecter des applications diverses appelées GauffrSlave qui vont utiliser le couple "login / mot de passe" issu d'une seule application déjà existante appelée GauffrMaster. Gauffr vous offre donc un niveau d'abstraction entre vos applications GauffrSlave et votre application maitresse que vous pouvez changer sans avoir à tout re-développer.

Les nouveautés de cette 0.9 sont essentiellement centrées autour de la GauffrAdmin qui permet de manipuler certaines données telles que les informations étendues qui vous permettent d'enrichir vos données maitresses sans en altérer le modèle de données ni le code.

Informations étendues sur les utilisateurs

Pour le moment, ces informations étendues sont essentiellement orientées vers les logins alternatifs, par exemple, si comme pour Fedora-Fr vous avez un login de type forums (llaumgui dans mon cas) et un login pour les wiki (GuillaumeKulakowski). A terme, j'envisage de stocker les informations OpenID mais surtout de permettre d'étendre ces données à partir d'un fichier de configuration.

Une autre fonctionnalité de la GauffrAdmin est de permettre de configurer les droits utilisateurs. Vous pouvez par exemple permettre à vos membres qui en ont le droit et seulement eux de se connecter au wiki, les plugins mwGauffr créera automatiquement le compte à la première connexion.

Droits utilisateur

Pourquoi la mise à jour vers PHP 5.3 peut génèrer beaucoup de log ?

Alexandre Frandemiche

Hier matin, pour des raisons de compatibilité de version avec un logiciel que je compte installer prochainement pour Communauté-SLA.org, j'ai mis à jour mon serveur et notamment php et son ensemble de module en version 5.3. Le logiciel en question, c'est Openmeetings. J'y reviendrai dans un prochain article.

Analyse des logs

PhpDepuis cette mise à jour de mon serveur dédié chez OVH, hier, j'ai remarqué que mes logs Apache devenaient de plus en plus gros !

Je m'en suis rendu compte grâce à cette commande :  du -sh * | sort -n

Un petit tour du coté de /var/log/httpd : ll /var/log/httpd/

    -rw-rr 1 root root 0 août 8 10:32 access_log
    -rw-rr 1 root root 1049 août 9 09:45 error_log
    -rw-rr 1 root root 284 août 9 00:38 ssl_access_log
    -rw-rr 1 root root 527 août 9 09:45 ssl_error_log
    -rw-rr 1 root root 288 août 9 00:38 ssl_request_log
    -rw-rr 1 root root 3481337 août 9 09:47 www.communaute-sla.org-access_log
    -rw-rr 1 root root 53300401 août 9 09:47 www.communaute-sla.org-error_log
    -rw-rr 1 root root 198900 août 9 09:44 www.ecohumanisemradical.org-access_log
    -rw-rr 1 root root 11434 août 9 08:13 www.ecohumanismeradical.org-error_log
    -rw-rr 1 root root 316073 août 9 09:47 www.slobberbone.net-access_log
    -rw-rr 1 root root 21509 août 9 09:15 www.slobberbone.net-error_log

Ah bah là, on peut constater que ça se remplit vite pour Communauté-SLA.org ... surtout pour un fichier purgé hier ...

tail -f -n 300 /var/log/httpd/www.communaute-sla.org-error.log

Tue Aug 09 09:42:01 2011 error client ip.ip.ip.ip PHP Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Europe/Berlin' for 'CEST/2.0/DST' instead in /var/www/blablabla.php on line 707

En effet, Pour l'accueil de Communauté-SLA.org, j'utilise la fonction date() pour afficher les différents flux sur l'accueil. Visiblement avec la mise à jour en 5.3 de php, ceci génère cette erreur lorsque le timezone n'est pas spécifié et ce, pour chaque appel de la méthode ...

Modification du php.ini

cp /etc/php.ini /etc/php.ini.save vi /etc/php.ini

;;;;;;;;;;;;;;;;;;; ; Module Settings ; ;;;;;;;;;;;;;;;;;;;

Date ; Defines the default timezone used by the date functions ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone date.timezone = "Europe/Paris"

Modifiez ce qui est en gras, donc dé-commentez la ligne et ajoutez-y votre timezone ! Il ne reste plus qu'à recharger la configuration Apache :

/etc/init.d/httpd reload

Et hop ! résolu !

Un chroot si rapide à créer

Patrice Ferlet

J'avais travaillé sur la documentation de chroot sur cette page: http://doc.fedora-fr.org/wiki/Utili... mais depuis, les choses ont changé. Febootstrap ne marche plus du tout comme avant... et j'ai trouvé une manière encore plus simple de créer une base chroot sans manipuler des fichiers de dépôts. Vous allez voir, c'est tellement simple que ça en est presque indécent.

Voilà la manière la plus facile que j'ai trouvé, par exemple pour encapluser "php-cli" dans un chroot:

cd ~
mkdir -p chroots/fedora-15-chroot
cd chroots
su -c 'yum --installroot=`pwd`/fedora-15-chroot --releasever=15 install php-cli -y'

C'est simple comme choux en fait...

Je crée un répertoire dans mon "home" (cd ~ et mkdir -p chroots/fedora-15-chroot). Ensuite je demande à yum d'installer php-cli dans le répertoire fedora-15-chroot. Comme je n'ai pas créé de fichier de dépots Fedora dans le répertoire de chroot, je spécifie simplement que je veux utiliser la version "15" de fedora. Notez que "releasever" est une contraction de "release version".

Et comme par enchantement, j'ai un chroot fonctionnel !

Là où c'est intéressant, c'est que je me passe de pas mal de configuration un peu compliqué. Il est alors facile de changer de --releasever en 16 pour tester la rawhide, ou une version inférieure...

Me reste plus qu'à voir comment fonctionne lxc (et je n'ai pas la dernière version de libvirt donc je n'ai pas encore l'accès facilité par virt-manager) et je vais pouvoir tester pas mal de choses, comme faire marcher des bases en jail, compiler des choses tordus ou voir comment péter un système sans avoir peur :)" class="smiley

Un chroot si rapide à créer

Patrice Ferlet

J'avais travaillé sur la documentation de chroot sur cette page: http://doc.fedora-fr.org/wiki/Utili... mais depuis, les choses ont changé. Febootstrap ne marche plus du tout comme avant... et j'ai trouvé une manière encore plus simple de créer une base chroot sans manipuler des fichiers de dépôts. Vous allez voir, c'est tellement simple que ça en est presque indécent.

Voilà la manière la plus facile que j'ai trouvé, par exemple pour encapluser "php-cli" dans un chroot:

cd ~
mkdir -p chroots/fedora-15-chroot
cd chroots
su -c 'yum --installroot=`pwd`/fedora-15-chroot --releasever=15 install php-cli -y'

C'est simple comme choux en fait...

Je crée un répertoire dans mon "home" (cd ~ et mkdir -p chroots/fedora-15-chroot). Ensuite je demande à yum d'installer php-cli dans le répertoire fedora-15-chroot. Comme je n'ai pas créé de fichier de dépots Fedora dans le répertoire de chroot, je spécifie simplement que je veux utiliser la version "15" de fedora. Notez que "releasever" est une contraction de "release version".

Et comme par enchantement, j'ai un chroot fonctionnel !

Là où c'est intéressant, c'est que je me passe de pas mal de configuration un peu compliqué. Il est alors facile de changer de --releasever en 16 pour tester la rawhide, ou une version inférieure...

Me reste plus qu'à voir comment fonctionne lxc (et je n'ai pas la dernière version de libvirt donc je n'ai pas encore l'accès facilité par virt-manager) et je vais pouvoir tester pas mal de choses, comme faire marcher des bases en jail, compiler des choses tordus ou voir comment péter un système sans avoir peur :)" class="smiley

Tester des paquets sans tout casser

Patrice Ferlet

Une des raisons pour laquelle j'utilise Fedora depuis des années c'est l'aptitude (clin d'oeil de geek...) de yum à permettre des manipulations de paquets assez rapide. J'avais justement besoin de tester llvm 2.9 qui est pour le moment dans les dépôts rawhide (c'est à dire dans les dépôts de développement de la future version de fedora). Donc, me voilà avec un dilemme: comment tester sans tout casser et sans me prendre la tête à installer une VM? La réponse est dans yum l'ami.

yum a deux options (en fait une commande et une option) qui me permettent de tester sans massacrer mon système: distro-sync et --releasever. La première fait en sorte de synchroniser mes versions de paquets à la version de fedora en cours, et l'autre me permet de spécifier la version de fedora à utiliser.

Et bien allons y gaiement:

su -
yum clean all
yum --releasever=rawhide --nogpgcheck --disablerepos=rpmfusion\* update llvm

Cela à pour effet de lancer une installation en spécifiant que je cherche des paquets pour rawhide. L'installation terminée, j'ai bien un llvm 2.9 qui est installé alors que sur Fedora 15 nous sommes en version 2.8.

Mes tests terminés (et non concluant) j'ai eut envie de revenir à ma version de base. Et bien c'est simple:

yum clean all
yum distro-sync

Et voilà, yum trouve des paquets à downgrader (réduire la version) et me réinstalle tous les paquets estampillés pour la version fedora supérieure à la version actuelle (ici fedora 15). Du coup j'ai resynchronisé ma fedora. Attention tout de même à ne pas faire ça pour n'importe quoi... n'oubliez pas que des fichier .rpmnew peuvent apparaître ou encore peuvent vraiment planter le système.

Personnellement j'évite de faire ça pour tout, par exemple pour le moment j'évite de jouer avec des version de gnome qui se trouve dans rawhide, mais pour ce qui est de certaines librairies, compilateurs, ou encore apache, php... j'aime bien tester de la sorte.

Effectivement lxc ou carrément une machine virtuelle pourrait faire l'affaire, mais c'est tellement sympa avec yum... non ?

Tester des paquets sans tout casser

Patrice Ferlet

Une des raisons pour laquelle j'utilise Fedora depuis des années c'est l'aptitude (clin d'oeil de geek...) de yum à permettre des manipulations de paquets assez rapide. J'avais justement besoin de tester llvm 2.9 qui est pour le moment dans les dépôts rawhide (c'est à dire dans les dépôts de développement de la future version de fedora). Donc, me voilà avec un dilemme: comment tester sans tout casser et sans me prendre la tête à installer une VM? La réponse est dans yum l'ami.

yum a deux options (en fait une commande et une option) qui me permettent de tester sans massacrer mon système: distro-sync et --releasever. La première fait en sorte de synchroniser mes versions de paquets à la version de fedora en cours, et l'autre me permet de spécifier la version de fedora à utiliser.

Et bien allons y gaiement:

su -
yum clean all
yum --releasever=rawhide --nogpgcheck --disablerepos=rpmfusion\* update llvm

Cela à pour effet de lancer une installation en spécifiant que je cherche des paquets pour rawhide. L'installation terminée, j'ai bien un llvm 2.9 qui est installé alors que sur Fedora 15 nous sommes en version 2.8.

Mes tests terminés (et non concluant) j'ai eut envie de revenir à ma version de base. Et bien c'est simple:

yum clean all
yum distro-sync

Et voilà, yum trouve des paquets à downgrader (réduire la version) et me réinstalle tous les paquets estampillés pour la version fedora supérieure à la version actuelle (ici fedora 15). Du coup j'ai resynchronisé ma fedora. Attention tout de même à ne pas faire ça pour n'importe quoi... n'oubliez pas que des fichier .rpmnew peuvent apparaître ou encore peuvent vraiment planter le système.

Personnellement j'évite de faire ça pour tout, par exemple pour le moment j'évite de jouer avec des version de gnome qui se trouve dans rawhide, mais pour ce qui est de certaines librairies, compilateurs, ou encore apache, php... j'aime bien tester de la sorte.

Effectivement lxc ou carrément une machine virtuelle pourrait faire l'affaire, mais c'est tellement sympa avec yum... non ?

Jouer avec le bash pour faire un benchmark

Patrice Ferlet

Avant toutes choses, je ne suis pas un dieu du bash, loin de là. J'avais besoin de faire un petit benchmark entre node.js, php et python. Et je vous avoues que j'avais pas très envie de créer des scripts partout pour une opération "one shot"... Connaissant un peu les capacités de bash, j'ai tapé instinctivement (je vous assure) les commandes que je vais vous expliquer. Le but était à la base de créer le moins de fichiers possibles. En fait tout ce dont j'avais besoin c'était de créer les fichier de résultats de temps et de visualiser un graphique. Vous allez voir que ce que je vais vous présenter ne crée que 3 fichiers, en fait un fichier de "log" de temps d'exécution par langage. Pour le reste, c'est bash qui va s'occuper de me rendre service, ainsi que le fabuleux gnuplot.

Juste une petite parenthèse, ce billet est surtout là pour montrer à quel point le terminal de commandes est puissant si l'on se penche un peu sur l'ensemble des commandes utiles. Un peu d'entrainement permet de régler des tas de soucis, mais aussi, comme dans mon cas présenté ici, de permettre des travaux qui peuvent paraître compliqués... mais finalement réglé en quelques minutes... Encore une fois, je connais bien Bash et cela vient naturellement, mais je n'ai pas plus d'aptitude que la plupart des linuxiens sur un terminal. Ma seule performance ici est d'avoir la folie et l'amour des lignes de commandes pour ce genre de process.

Très bien, pour être précis mes benchmarks se portaient sur le calcul de 32 rangs de la suite de fibonnacci. Pour ceux qui ne la connaissent pas, je vous la présente rapidement: 0 1 1 2 3 5 8 13 etc...

En fait c'est simple, on part de 0 puis 1, ensuite il faut ajouter les deux nombres précédents pour trouver le nombre du rang "n".

  • 0 et 1 engendre: 0+1=1
  • la suite est donc 0 1 1
  • ensuite je prend les deux derniers chiffres: 1 et 1, je les additionne: 1+1=2
  • la suite devient 0 1 1 2
  • on continue de la même manière, les deux derniers chiffres de la suite étant 1 et 2: 1+2=3
  • la suite devient 0 1 1 2 3
  • et ainsi de suite, les deux derniers chiffre étant 2 et 3: 2+3=5
  • la suite devient 0 1 1 2 3 5
  • etc...

Algorithmiquement, cela peut se résoudre par une fonction itérative:

fonction fibo (n)
    si n vaut 0 ou 1 on retroune n
    sinon on retourne fibo(n-2)+fibo(n-1)

Ok, pour python, php et node (javascript) cela va se faire en 3 ou 4 lignes... et plutôt que de créer un script, je fais appel aux interpréteurs directement en ligne de commande. Par exemple pour avoir le rang 10 en PHP:

php -r '
function fibo ($n) {
return ($n==0 || $n==1) ? $n : fibo($n-1)+fibo($n-2);
}
fibo(10);
'

Ça fonctionne bien.

Reste que je veux calculer tous les rangs allant de 0 à 32... et bien bash me permet de boucler:

for i in $(seq 1 32)
do
php -r '
function fibo ($n) {
return ($n==0 || $n==1) ? $n : fibo($n-1)+fibo($n-2);
}
fibo('$i');
done

Pas mal... mais il me reste un truc à faire, chronométrer le processus... alors oui je sais, il existe la commande "time" mais elle est pas si simple à gérer en terme de sortie, moi j'ai besoin d'avoir juste le temps total, seconde et milisecondes comprises... et bien c'est simple, on va enregistrer le timestamp + les nanosecondes via la commande "date" avant puis après le processus. Il suffira de soustraire les temps pour avoir le différenciel.

Voilà comment je benchmark PHP:

for i in $(seq 1 32); do 
echo -n $i" "
_s=$(date +%s.%N)
php -r '
function fibo ($n) {
return ($n==0 || $n==1) ? $n : fibo($n-1)+fibo($n-2);
}
fibo('$i');
'
echo $(date +%s.%N)-$_s | bc -l
unset _s
done

Je vous explique. je boucle 32 fois sur la suite de commande:

  • echo -n $i" " : pour savoir où j'en suis, j'ajoute un espace après le nombre, et j'utilise "-n" pour ne pas revenir de suite à la ligne
  • _s=$(date +%s.%N) : je place la date en timestamp (nombre de secondes depuis 1970) suivit de "." et les nanosecondes en cours
  • php -r... : on exécute le code php
  • echo $(date +%s.%N)-$_s | bc -l : j'écris l'opération "date courante avec nanoseconde" - "date enregistré avant le process" et je l'envois à "bc -l" qui va calculer ça
  • unset _s : juste pour virer la vairable $_s qui va plus nous servir.

Bon, vous avez compris, me reste plus qu'à enregistrer le résultat dans un fichier. Je vais donc dans /tmp et je crée un répertoire "bench":

mkdir /tmp/bench
cd /tmp/bench

et je fais le logs, pour PHP en premier (dieu que c'est lent...):

for i in $(seq 1 32); do 
echo -n $i" "
_s=$(date +%s.%N)
php -r '
function fibo ($n) {
return ($n==0 || $n==1) ? $n : fibo($n-1)+fibo($n-2);
}
fibo('$i');
'
echo $(date +%s.%N)-$_s | bc -l
unset _s
done>php.log

On fait pareil pour node:


for i in $(seq 1 32)
do
echo -n $i" "; _s=$(date +%s.%N);
node <<JS
function fibo(n) {
return (n==0 || n==1 ) ? n : fibo(n-2)+fibo(n-1);
}
fibo($i);
JS
echo $(date +%s.%N)-$_s | bc -l; 
unset _s; 
done>node.log

et enfin pour python:

for i in $(seq 1 32)
do 
echo -n $i" "
_s=$(date +%s.%N); python -c '
def fibo(n):
   return n if (n==0 or n==1) else fibo(n-1)+fibo(n-2)
fibo('$i')
'
echo $(date +%s.%N)-$_s | bc -l; 
unset _s; 
done>python.log

J'ai donc là 3 fichier qui contiennent chacun des logs de temps, je vous montre celui de PHP:

$ cat php.log 
1 .036828663
2 .025703992
3 .026992606
4 .033444640
5 .035266864
6 .033452564
7 .028677243
8 .036187726
9 .035308338
10 .033860607
11 .030994306
12 .031643060
13 .030666493
14 .033131695
15 .037534009
16 .034849018
17 .036111420
18 .042433952
19 .044907994
20 .052853506
21 .068992452
22 .086515691
23 .125384399
24 .180959996
25 .279442730
26 .412510010
27 .648189657
28 1.019483322
29 1.626384710
30 2.644171263
31 4.257360111
32 6.938595991

Mon souci va être d'utiliser les 3 fichiers en même temps dans gnuplot... plutôt que de passer par 3 commandes en entrée (je vais vous montrer comment on fait dans gnuplot) je vais utiliser une commande que j'adore: paste

Cette commande est magique, elle "colle" en colonnes les fichiers les uns à coté des autres, voici ce que ça donne chez moi:

$ paste *.log
1 .065706975    1 .036828663    1 .051057606
2 .075880231    2 .025703992    2 .046552158
3 .073986169    3 .026992606    3 .046123806
4 .073072239    4 .033444640    4 .042877291
5 .070891448    5 .035266864    5 .045012469
6 .074523262    6 .033452564    6 .047550418
7 .072727132    7 .028677243    7 .042658307
8 .075226716    8 .036187726    8 .045704715
9 .069166717    9 .035308338    9 .046088504
10 .071344391   10 .033860607   10 .043567632
11 .072756556   11 .030994306   11 .043765426
12 .073284181   12 .031643060   12 .043340776
13 .072755513   13 .030666493   13 .045153174
14 .068839918   14 .033131695   14 .047908738
15 .079993544   15 .037534009   15 .050165910
16 .072923693   16 .034849018   16 .048907127
17 .074823342   17 .036111420   17 .047513241
18 .073899009   18 .042433952   18 .053685052
19 .069858333   19 .044907994   19 .048828831
20 .071467252   20 .052853506   20 .050347929
21 .073423093   21 .068992452   21 .049505150
22 .074624496   22 .086515691   22 .060360949
23 .071165563   23 .125384399   23 .068465359
24 .076328627   24 .180959996   24 .079916752
25 .076409643   25 .279442730   25 .100771059
26 .079967605   26 .412510010   26 .136666736
27 .076491429   27 .648189657   27 .198588958
28 .085810737   28 1.019483322  28 .293586222
29 .095436353   29 1.626384710  29 .434787310
30 .104759161   30 2.644171263  30 .675019713
31 .125979134   31 4.257360111  31 1.074293193
32 .155473948   32 6.938595991  32 1.705526686

S'en est presque poétique... non ? Vous avez remarqué qu'on a besoin ici des colonnes 1, 2, 4 et 6 pour avoir la valeur de 'n' et le temps d'exécution pour chaque langage. Notez aussi que les colonnes représentent les fichier dans l'ordre alphabétique du nom du fichier de log, ainsi de gauche à droite on a "node", puis "php" et enfin "python"...

Bon on passe à gnuplot, on lance la commande gnuplot et on tape ceci:

gnuplot> set title "Benchmark Fibonnacci"
gnuplot> set xlabel "n value"
gnuplot> set ylabel "time in seconds"
gnuplot> set grid
gnuplot> plot "< paste *.log" using 1:2 with line title "node", "< paste *.log" using 1:4 with line title "php",  "< paste *.log" using 1:6 with line title "python"

Je sais que j'aurais put utiliser les fichier les uns après les autres mais la commande "paste" me permet des copier/coller rapides de mes commandes sans avoir à changer le nom du fichier à chaque fois... et puis je voulais vous parler de cette commande d'abord hein !

Bref, le résultat est de cette forme: Fibonnacci benchmark gnuplot

Vous l'aurez donc compris, en maitrisant un peu le bash on peut effectuer des opérations assez poitilleuses sans pour autant à avoir à gérer un projet complet de scipts... le tout est de s'entrainer, et tout devient instinctif.

Je le répète, j'ai fait ces opérations sans me poser de questions, et comme je me suis rendu compte que ça pourrait intéresser certains... je me suis dit qu'il serait bon de montrer un peu comment je procède.

Et bien voilà, explication terminée. En espérant que ça vous ait donné envie de taper des lignes de commandes plutôt que de passer par un tableur... ;)" class="smiley

PS: désolé pour les fautes dorthographe mais j'ai du mal à les trouver ce soir... je corrigerai demain...

XHTML2ODT sort en version 1.3

Aurélien Bompard

Après environ 1 an de développements épisodiques, voici une nouvelle version de la bibliothèque XHTML 2 ODT, permettant de convertir du HTML bien formé en ODT, le format standard de bureautique.

Parmi les nouveautés, des améliorations de conversion de certaines balises (dl et span par exemple), des améliorations dans la gestion des images, l’ajout de paquets RPM et Deb, et la gestion du HTML généré par Lyx et Elyxer.

En ce qui concerne le packaging, des paquets RPM et Deb sont générés par le OpenSuSE Build Service, qui est un outil vraiment très intéressant quand on cible plusieurs distributions. Pour cette version, j’ai aussi créé un feed Zero Install. Zero Install est une méthode d’installation d’applications qui vient en parallèle du système natif de la distribution (mais qui s’intègre avec). C’est très utile pour des applications qui sont mis à jour très fréquemment, comme Firefox par exemple, ou pour distribuer une application sous une forme indépendante de la distribution. Je vous laisse creuser le sujet si ça vous intéresse, mais c’est un ensemble d’outils qui mériteraient d’être plus connus.

Rendez-vous sur le site du projet xhtml2odt ou directement sur la page de téléchargement pour récupérer la dernière version de la bibliothèque.

Erreur lors de l'installation d'Eclipse sous CentOS 5

Alexandre Frandemiche

Bonjour à tous,

Ce matin en voulant rejouer un bug de notre solution d'optimisation et de planification de techniciens mobiles (Opti-Time RMS et GOS). J'ai eu besoin d'installer un environnement de debug sur une CentOS 5 Server. D'ailleurs, vous aurez remarqué (ou pas) que le site Internet d'Opti-Time est flambant neuf !! Et sous Drupal ! Le libre s'installe de plus en plus chez nous et ce n'est pas pour me déplaire !

J'ai d'abord dû installer une interface graphique :
su -lc 'yum groupinstall "X Window System" "Environnement de bureau GNOME"'

Puis vient le moment d'installer Eclipse : su -lc 'yum install eclipse-platform' Hors en voulant installer le paquet 'eclipse-platform' j'ai obtenu l'erreur suivante :

Missing Dependency: /usr/bin/rebuild-security-providers is needed by package java-1.4.2-gcj-compat-1.4.2.0-40jpp.115.x86_64 (installed)

En effet, il se peut qu'au niveau de mes dépôts, entre EPEL, CentOS Plus et surtout ceux d'Opti-Time, il y ait des petits soucis au niveau de java ... même si je ne vois pas trop où ... par soucis d'efficacité, je n'ai pas chercher à comprendre !

Voici la solution détaillée : JPackage jpackage-utils compatibility for CentOS 5.x , sinon vous pouvez tout simplement faire ce qui suit :
su -lc 'rpm ivh http://plone.lucidsolutions.co.nz/linux/centos/images/jpackage-utils-compat-el5-0.0.1-1.noarch.rpm/at_download/file'

Attention à bien autoriser l'installation malgré la clé gpg inconnue !

Une fois fait, on peut reprendre l'installation d'Eclipse :
su -lc 'yum install eclipse-platform'

Et voilà, maintenant, je n'ai plus qu'à récupérer mes sources ... mais là, ça ne vous intéresse plus ;) !

Erreur lors de l'installation d'Eclipse sous CentOS 5

Alexandre Frandemiche

Bonjour à tous,

Ce matin en voulant rejouer un bug de notre solution d'optimisation et de planification de techniciens mobiles (Opti-Time RMS et GOS). J'ai eu besoin d'installer un environnement de debug sur une CentOS 5 Server. D'ailleurs, vous aurez remarqué (ou pas) que le site Internet d'Opti-Time est flambant neuf !! Et sous Drupal ! Le libre s'installe de plus en plus chez nous et ce n'est pas pour me déplaire !

J'ai d'abord dû installer une interface graphique :
su -lc 'yum groupinstall "X Window System" "Environnement de bureau GNOME"'

Puis vient le moment d'installer Eclipse : su -lc 'yum install eclipse-platform' Hors en voulant installer le paquet 'eclipse-platform' j'ai obtenu l'erreur suivante :

Missing Dependency: /usr/bin/rebuild-security-providers is needed by package java-1.4.2-gcj-compat-1.4.2.0-40jpp.115.x86_64 (installed)

En effet, il se peut qu'au niveau de mes dépôts, entre EPEL, CentOS Plus et surtout ceux d'Opti-Time, il y ait des petits soucis au niveau de java ... même si je ne vois pas trop où ... par soucis d'efficacité, je n'ai pas chercher à comprendre !

Voici la solution détaillée : JPackage jpackage-utils compatibility for CentOS 5.x , sinon vous pouvez tout simplement faire ce qui suit :
su -lc 'rpm ivh http://plone.lucidsolutions.co.nz/linux/centos/images/jpackage-utils-compat-el5-0.0.1-1.noarch.rpm/at_download/file'

Attention à bien autoriser l'installation malgré la clé gpg inconnue !

Une fois fait, on peut reprendre l'installation d'Eclipse :
su -lc 'yum install eclipse-platform'

Et voilà, maintenant, je n'ai plus qu'à récupérer mes sources ... mais là, ça ne vous intéresse plus ;) !

Twitter en ligne de commande

Remi Collet

Il y a quelque temps, j'avais proposer un petit script pour Twitter en ligne de commande. Avec la disparition de l'authentification simple, je me suis attelé à écrire une nouvelle version.

Comme toujours, j'ai écrit mon application en PHP et j'utilise l'extension Oauth disponible depuis peu dans les dépôts fedora (et remi pour les anciennes versions ou Enterprise linux). Vous pouvez la récupérer sur https://github.com/remicollet/twit. Un exemple qui m'a bien aidé : Using pecl/oauth to post to Twitter Installation $ su -c "yum... Lire Twitter en ligne de commande

Créer un fichier Excel à partir d'un script

Fabien Nicoleau

J'ai récemment eu besoin de générer despuis un script un "vrai" fichier Excel. J'entends par "vrai", un fichier qui ne s'importe pas, mais qui s'ouvre directement et qui puisse contenir de la mise en forme. En recherchant sur internet, j'ai découvert que OpenOffice et Microsoft Excel (et peut-être d'autres tableurs) savent ouvrir un fichier content une description de table au format HTML. En plus, ils savent gérer des styles (de type CSS). Tout est donc imaginable, sauf que se pose le problème récurent des formats de cellule. N'ayant à travailler que pour Excel (on ne choisit pas toujours ses outils!), j'ai trouvé sur internet une solution pour celui-ci. En effet, il prends en compte la directive mso-number-format permettant de définir le format de la cellule. Ce billet indique différents exemples de valeurs possibles pour définir les formats.

Ainsi j'ai pu, à grand coup de echo et de redirection de flux, générer des fichiers Excel avec de bons formats pour les dates, les chiffres, forcer du texte (notamment pour les chaines ne contenant que des chiffres), et ajouter un peu de mise en forme.

Histoire de servir d'exemple, et pour moi de pense-bête, voici le contenu d'un fichier xls qui peut être généré avec différents exemples de formatage de cellule :

<style>
   .date {mso-number-format:"dd/mm/yy"}
   .txt {mso-number-format:"\@";}
   .gras {font-weight:bold;}
   .centreGras {font-weight:bold; text-align:center}
   .fondRouge {background-color : red}
   .enJaune {color:yellow}
   .titreVoyant {background-color:green;color:cyan;font-weight:bold}
   .3dec {mso-number-format:"\#\, \#\#0\.000"}
</style>

<table border="1">
<tr><td class="txt">00001</td><td class="gras">En gras</td><td class="centreGras">Au centre, en gras</td></tr>
<tr><td>00001</td><td class="fondRouge">fond rouge</td><td class="enJaune">en jaune</td></tr>
<tr><td class="titreVoyant">FLASH !</td><td class="date">25/01/2011</td><td class="3dec">10254,25689744541</td></tr>
<tr class="gras"><td>toute la </td><td>ligne </td><td>en gras</td></tr>
</table>

Voici le rendu dans Excel :

excelhtml.JPG

Notez que les cases A1 et A2 contiennent la même valeur, mais A1 étant formaté en texte, les zéros sont bien affichés. Pour l'instant je n'ai pas réussi à appliquer plusieurs classes à une même cellule, ce qui force à créer des classes spécifiques avec plusieurs mises en forme.

Voilà donc une solution rapide qui permettra, lorsque le langage de programmation ou de script utilisé ne contient pas de module pour gérer le format xls, de générer des fichiers Excel correctement formatés.


Fabien (eponyme)

Créer un fichier Excel à partir d'un script

Fabien Nicoleau

J'ai récemment eu besoin de générer despuis un script un "vrai" fichier Excel. J'entends par "vrai", un fichier qui ne s'importe pas, mais qui s'ouvre directement et qui puisse contenir de la mise en forme. En recherchant sur internet, j'ai découvert que OpenOffice et Microsoft Excel (et peut-être d'autres tableurs) savent ouvrir un fichier content une description de table au format HTML. En plus, ils savent gérer des styles (de type CSS). Tout est donc imaginable, sauf que se pose le problème récurent des formats de cellule. N'ayant à travailler que pour Excel (on ne choisit pas toujours ses outils!), j'ai trouvé sur internet une solution pour celui-ci. En effet, il prends en compte la directive mso-number-format permettant de définir le format de la cellule. Ce billet indique différents exemples de valeurs possibles pour définir les formats.

Ainsi j'ai pu, à grand coup de echo et de redirection de flux, générer des fichiers Excel avec de bons formats pour les dates, les chiffres, forcer du texte (notamment pour les chaines ne contenant que des chiffres), et ajouter un peu de mise en forme.

Histoire de servir d'exemple, et pour moi de pense-bête, voici le contenu d'un fichier xls qui peut être généré avec différents exemples de formatage de cellule :

<style>
   .date {mso-number-format:"dd/mm/yy"}
   .txt {mso-number-format:"\@";}
   .gras {font-weight:bold;}
   .centreGras {font-weight:bold; text-align:center}
   .fondRouge {background-color : red}
   .enJaune {color:yellow}
   .titreVoyant {background-color:green;color:cyan;font-weight:bold}
   .3dec {mso-number-format:"\#\, \#\#0\.000"}
</style>

<table border="1">
<tr><td class="txt">00001</td><td class="gras">En gras</td><td class="centreGras">Au centre, en gras</td></tr>
<tr><td>00001</td><td class="fondRouge">fond rouge</td><td class="enJaune">en jaune</td></tr>
<tr><td class="titreVoyant">FLASH !</td><td class="date">25/01/2011</td><td class="3dec">10254,25689744541</td></tr>
<tr class="gras"><td>toute la </td><td>ligne </td><td>en gras</td></tr>
</table>

Voici le rendu dans Excel :

excelhtml.JPG

Notez que les cases A1 et A2 contiennent la même valeur, mais A1 étant formaté en texte, les zéros sont bien affichés. Pour l'instant je n'ai pas réussi à appliquer plusieurs classes à une même cellule, ce qui force à créer des classes spécifiques avec plusieurs mises en forme.

Voilà donc une solution rapide qui permettra, lorsque le langage de programmation ou de script utilisé ne contient pas de module pour gérer le format xls, de générer des fichiers Excel correctement formatés.


Fabien (eponyme)

Migration de mon blog en HTML5

Guillaume Kulakowski

Ça fait un petit moment que je n'avais pas travaillé sur mon blog... Il faut dire que la v5 de Fedora-Fr m'a pris pas mal de temps. Mais maintenant que c'est à peu près fini, je me suis lancé dans le portage du thème de mon blog en HTML5.

Au programme :

  • utilisation des "role" : banner, main, complementary, etc...
  • utilisation des nouvelles balises : section, article, header, footer
  • Formulaire : aria, placeholder (le truc le plus visible), etc...

Pour moi les avantages de l'HTML5 sont :

  • La sémantique web grâce aux nouvelles balises et au rôles. Une meilleure sémantique est selon moi gage d'un meilleur référencement.
  • La mobilité, qui fera l'objet de mon prochain travail...

Pour réaliser ce portage, je me suis basé sur ces différentes ressources :

J'ai également profité de cette mise à jour pour :

  • Rajouter la validation des formulaires en JavaScript,
  • Passer les icônes de réseaux sociaux en CSS sprite,
  • Rajouter Linkedin,
  • Migrer sous jQuery 1.5 et utiliser le CDN de Google,
  • Améliorer l'interface d'administration du thème de ce blog (cf capture).

Configuration du thème Emplode HTML5

Comment écrire du code testable

Aurélien Bompard

Je vous propose les diapositives d’une présentation que j’ai réalisée récemment, concernant les méthodes de développement permettant d’écrire un code facilement testable.

Il y a quelques semaines, j’ai visionné la présentation de Miško Hevery chez Google à ce sujet, et j’ai tout de suite été conquis par sa clarté et son pragmatisme. Avec son accord, j’ai entrepris de la traduire et de l’adapter en français.

Mon objectif était avant tout de garder une présentation généraliste (indépendante du langage de programmation, du framework ou du projet), et de pouvoir l’utiliser dans le cadre de mon travail pour essayer de diffuser les bonnes habitudes de la testabilité auprès de mes collègues.

J’ai finalement eu l’occasion de donner cette présentation sur mon lieu de travail, qui s’est très bien passée, mais dont l’enregistrement n’est malheureusement pas diffusable. Quoi qu’il en soit, j’ai pu tester “en conditions réelles” la qualité des diapos et l’importance des concepts présentés par Miško.

Si le sujet vous intéresse, j’attache à ce billet le fichier ODP[1] de la présentation. Les points à aborder oralement sont dans la section “notes” de chaque diapo, pensez-donc à la lire. De plus, certaines diapos utilisent des animations, il est donc préférable de lire la présentation en mode “diaporama”.

Quand j’ai demandé à Miško si je pouvais réutiliser ses diapos, il n’a demandé qu’une citation de son nom. Dans le même esprit, je place donc cette présentation sous licence Creative Commons Attribution (BY), c’est à dire que vous pouvez la réutiliser comme bon vous semble à condition de citer le nom des auteurs (Miško et moi).

Pour pouvoir comprendre et suivre cette présentation, il faut connaître au minimum les concepts suivants :

  • Programmation Orientée Objet
  • Quelques design patterns courants (Factory et Singleton)
  • Tests unitaires

Les sujets abordés au cours de la présentation sont :

  • Le développement piloté par les tests (ou Test-driven development)
  • L’injection de dépendances
  • La loi de Déméter
  • La théorie des bugs (par Miško)

Les exemples de codes utilisés dans la présentation sont en Python, parce que c’est le langage que je maîtrise le mieux et celui avec lequel je travaille au quotidien, mais les concepts sont applicables à n’importe quel autre langage. De plus, un des principaux exemples de code est disponible aussi en Java, pour ceux qui préfèrent.

La présentation dure environ une heure. Si vous décidez de réutiliser ces diapos, vous n’êtes évidemment pas obligés de m’en faire part, mais j’aimerais bien si possible avoir des retours pour les améliorer et intégrer les meilleures remarques.

J’espère que ces diapos pourront vous aider à diffuser la “bonne parole” de la testabilité aussi largement que possible !

Notes :

[1] S’ouvre avec LibreOffice ou OpenOffice.

QtScript : exemple d'utilisation

Fabien Nicoleau

J'ai essayé dans mon billet précédent de démystifier QtScript et de montrer au travers de différents exemples quelques unes des possibilités offertes par ce module de la bibliothèque Qt. Après ces premiers pas, je vous propose ici d'utiliser QtScript dans un exemple concret. Il s'agira de créer une calculatrice pour laquelle chaque type d'opération possible sera un plugin développé en JavaScript. Il sera ainsi possible "d'étendre" cette calculatrice comme bon vous semble en codant de nouveaux types d'opérations. Cependant je m'en tiendrai dans cet exemple aux simples addition, soustraction, multiplication et division. J'ai appelé ce petit projet QtExCalc pour Qt Extendable Calculator.

Le projet

Pour commencer, assurez vous que le package qt-devel est installé sur votre poste. Si ce n'est pas le cas, sous Fedora, tapez :

# yum install qt-devel

Il faudra ensuite télécharger les sources du projet, dont vous trouverez l'archive jointe à ce billet. Une fois cette dernière décompressée, déplacez vous dans le dossier qtexcalc puis tapez :

$ qmake-qt4
$ make

Le projet est alors compilé. Vous pouvez l'exécuter :

$ ./qtexcalc

L'application se lance :

capture1.jpg

Elle est très simple. Choisissez un type d'opération proposé dans la liste, saisissez deux nombre, puis cliquez sur le bouton pour afficher le résultat. Tout l'intérêt de ce programme est donc qu'il est modulable, grâce à des scripts JS. A son lancement, elle charge des plugins placés dans le sous-répertoire plugins. Chaque plugin fourni trois informations :

  • Le libellé de son opération, qui sera affiché dans la liste ("Addition" par exemple)
  • Le signe de son opération, qui sera affiché sur le bouton ("+" par exemple)
  • Une procédure de traitement, prenant deux chiffres en paramètre, et renvoyant un résultat. Le traitement effectué est évidemment propre à chaque plugin

Le code

Les sources sont composées d'une classe Dialog comprennant la fenêtre principale, ainsi que les différents traitements associés aux actions de l'utilisateur, une classe Plugin, dont chaque instance "représentera" un des plugins, et qui sera chargée de dialoguer avec. Enfin, un fichier main, simplement chargé de créer la fenêtre principale et de l'afficher. Passons au code.

main.cpp

C'est le seul fichier dont je copierai intégralement le contenu ici, tant il est petit :

#include <QtGui/QApplication>
#include "dialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();
    return a.exec();
}

Comme expliqué plus tôt, on se contente ici d'afficher la fenêtre du projet.

Classe Plugin

Cette classe a en charge de dialoguer avec le plugin. Elle contient trois méthodes dont voici l'implémentation :

Plugin::Plugin(QScriptEngine* eng)
{
    this->engine = eng;
    this->sign =this->engine->globalObject().property("getOperationSign").call(QScriptValue()).toString() ;
}

QString Plugin::getSign() {
    return this->sign;
}

double Plugin::compute(double num1, double num2) {
    return this->engine->globalObject().property("compute").call(QScriptValue(),QScriptValueList() << num1<<num2).toNumber();
}

Le constructeur prend en paramètre un pointeur sur un moteur de script, qui permettra de dialoguer avec le plugin, et récupère ensuite le signe de l'opération du plugin en appelant sa fonction getOperationSign()

La méthode getSign() renvoie le signe de l'opération du plugin qui a été stocké dans le constructeur.

Enfin, la méthode compute() se charge d'effectuer l'opération. Elle attend deux paramètres qui seront passés à la fonction compute() du plugin. Elle renvoie ensuite le résultat de l'opération.

Classe Dialog

Voici la principale classe du projet. Je laisse de coté ici tout ce qui concerne la gui, pour ne se concentrer que sur QtScript. Commençons par la méthode loadPlugins() qui est appelée lors de la construction de l'objet et qui permet de "charger" les différents plugins :

void Dialog::loadPlugins() {
    QDir dirPlugins("plugins");
    QString fName;
    QScriptEngine * engine;
    QComboBox * cbPlugins = this->ui->cbChoosePlugin;
    cbPlugins->addItem(QString::fromUtf8 ("Choisissez une opération ..."),"");
    foreach(fName,dirPlugins.entryList(QStringList() << "*.qs")) {
        engine = new QScriptEngine();
        QFile file("plugins/"+fName);
        file.open(QIODevice::ReadOnly);
        engine->evaluate(file.readAll());
        file.close();
        cbPlugins->addItem(engine->globalObject().property("getOperationName").call(QScriptValue()).toString(),fName);
        this->plugins[fName] = new Plugin(engine) ;
    }
}

Tous les fichiers dont l'extension est qs (pour QtScript, mais on peut bien sûr utiliser ce qu'on veut) sont listés grâce à la méthode entryList(). Pour chacun des fichiers, on créé un moteur de script puis on évalue le contenu. Ensuite, on ajoute à la liste (addItem()) le nom de l'opération, en appelant la fonction getOperationName du plugin, et on donne le nom du fichier (fName) comme data. Enfin, on construit un nouvel objet Plugin auquel on passe en paramètre le moteur et que l'on stocke dans une QMap, avec le nom de fichier (fName toujours) comme clé. Ainsi, lorsqu'une opération sera choisie dans la liste, on récupèrera le data (correspondant au nom de fichier) grâce auquel on pourra accéder à l'objet correspondant de la QMap.

Passons maintenant au slot choosedPlugin appelé à chaque fois que l'on sélectionne un item dans la liste des opérations :

void Dialog::choosedPlugin(int index) {
    if(index>0) {
        this->ui->bProcess->setText(this->plugins[this->ui->cbChoosePlugin->itemData(index).toString()]->getSign());
        this->ui->bProcess->setEnabled(true);
    }
    else {
        this->ui->bProcess->setText("");
        this->ui->bProcess->setEnabled(false);
    }
}

On vérifie tout d'abord que l'on a pas sélectionné le premier élément, qui est celui demandant de choisir une opération. Si on a bien sélectionné une opération, on récupère la donnée de l'élément (itemData()) sélectionné, qui nous permet d'accéder à l'objet Plugin correspondant, depuis lequel on appelle la méthode getSign(). Le signe de l'opération est appliqué au bouton, qui est ensuite activé.

Passons au dernier slot, compute, appelé lorsque l'utilisateur clique sur le bouton :

void Dialog::compute() {
    if(!this->ui->leNumber1->text().isEmpty() && ! this->ui->leNumber2->text().isEmpty() ) {
        Plugin * selectedPlugin = this->plugins[this->ui->cbChoosePlugin->itemData(this->ui->cbChoosePlugin->currentIndex()).toString()];
        this->ui->lResult->setText(QString::number(selectedPlugin->compute(this->ui->leNumber1->text().toDouble(),this->ui->leNumber2->text().toDouble())));
    }
}

Si les deux champs de saisie ont été remplis, on récupère l'objet Plugin de l'opération sélectionnée. On appelle la méthode compute() du Plugin, en lui passant en paramètre la valeur des champs de saisie, qui nous retourne le résultat de l'opération, résultat que l'on affiche dans le libellé correspondant.

Voici pour terminer, le code du plugin "addition", je ne donne pas le code des 3 autres, qui se devine facilement, et qui est dispo dans les sources :

function getOperationName() {
    return "Addition";
}

function getOperationSign() {
    return "+";
}

function compute(num1,num2) {
    return num1+num2;
}

On y voit donc les trois fonctions nécessaires, donnant le libellé de l'opération, son signe, et enfin le résultat de l'opération.

Voilà pour l'explication de ce petit projet, qui j'espère vous permettra de voir de quelle façon on peut facilement avec Qt gérer des plugins écrits en JavaScript. Si vous avez des questions sur le code, n'hésitez pas à les poser dans les commentaires.


Bon dev'

Fabien (eponyme)