eponyme's blog : linux, dev & cie

Développement

Ma principale activitée, scripts, C++, Java, Web 2.0 ...

Fil des billets - Fil des commentaires

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

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)

QtScript : exemple d'utilisation

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.

Premiers pas avec QtScript

Dans un précédent billet, j'avais parlé de la possibilité d'intégrer très facilement dans vos applications Java des scripts écrits en JavaScript, et de la facilité avec laquelle vos applications peuvent interagir avec les scripts. J'avais ensuite proposé un exemple d'utilisation avec un robot IRC fonctionnant avec des plugins écrits en JavaScript.

La bibliothèque Qt permet elle aussi d'intégrer des scripts JavaScript dans vos applications. Je propose ici de découvrir comment le faire, à travers quelques exemples simples.

Scripts JS avec Java et Rhino : mise en œuvre avec un bot IRC

Je montrais dans mon billet précédent que grâce à Rhino il est possible d'exécuter du code JavaScript depuis un programme Java, et comment il possible de se servir de ce système pour gérer des plugins. Je propose dans ce billet de mettre en œuvre ces fonctionnalités et de les appliquer à un projet simple : un robot IRC modulaire. Le principe est d'avoir un robot écrit en Java et capable de se connecter à un serveur IRC, puis de communiquer avec lui (envoi et réception de messages). Nous n'ajouterons rien à ce programme Java, aucun savoir faire pour ce robot, à une exception prêt : la possibilité de stocker des plugins qui lui permettront d'avoir de nouvelles fonctionnalités. Attention, le sujet de ce billet n'étant pas le codage d'un robot IRC (il y en a de meilleurs pour ca ^^), celui présenté ici est ultra simple, et se contente du minimum.

Pour comprendre ce programme, il faut avoir quelques notions sur Rhino/Java, des notions sur les expressions régulières, et notamment les groups qui seront bien utiles ici, et savoir en gros ce qu'est un client IRC.

Java : gérer facilement des plugins JavaScript

Dans une application, il peut être parfois intéressant d'extraire une partie de l'intelligence afin de répondre à un besoins sépcifique. Un exemple courant est une application fournie à différents clients. Elle comporte un socle commun, puis les spécificités sont développées dans des plugins afin de ne pas avoir à toucher au code de l'application pour une demande particulière. L'autre intérêt est de pouvoir charger dans une application des fonctionnalités supplémentaires, permettant de réduire le poids de l'application en retirant des fonctionnalités inutilisées. Le fait d'avoir du code externe permet aussi d'en facilité les mises à jour.

En Java, il est possible de créer des plugins de différentes façons : avec des classes externes, chargées grâce à un ClassLoader, grâce à groovy, très populaire, ou encore jython, permettant d'exécuter du code Python depuis un programme Java. Il existe de nombreuses autres solutions, comme celle d'utiliser le moteur JavaScript de la fondation Mozilla : Rhino. Sa particularité est qu'il est fourni par défaut avec Java depuis la version 6.

En ayant eu besoin pour un projet, et ayant trouvé peu d'aide en français, je propose ici quelques exemples très basiques afin de mettre en place un système de plugins JavaScript avec Java. 90% de l'aide dont j'ai eu besoin a été trouvée sur cette page de documentation. Je reprends donc ici quelques exemples, commentés, afin de comprendre le principe et d'imaginer les possibilités qu'offre Rhino. N'hésitez pas à poser des questions dans les commentaires si vous avez besoins de précisions.

Projets en cours

Ces derniers temps mon blog est plutôt inactif ... Pourtant "l'effet été" n'y est pour rien, et ce n'est pas non plus la cause d'une quelconque démotivation. Après la dernière release de trustyRC, j'ai décidé de faire une pause car la prochaine version devrait être majeure et contenir de nombreux changements radicaux. J'ai profité de ce temps pour retoucher un peu à Java, et découvrir un tas de nouvelles choses pour moi (ant et gcj notamment). Deux intérêt : me replonger dans ce langage que j'apprécie, et pouvoir poser plein de questions à Pikachu_2014 pour profiter de son légendaire savoir ! Je n'ai rien fait d'original, j'ai tout simplement recommencé une version de trustyRC en java (non, je ne bloque pas sur les bots IRC, c'est juste que ça intègre différentes notions et que c'est donc assez formateur). Vu que la chose me plait bien, je continue pour le moment, je verrai bien où ca me mène. La version C++ n'est pas pour autant arrêtée. Selon l'état d'avancement de la version Java le jour ou je déciderai de reprendre activement le développement de trustyRC, je verrai quelle version je garde, ou si je garde les deux. En parallèle je pense me lancer dans un petit jeu de bataille navale en réseau, intégrant un chat, etc ... Pour cela encore l'éternelle question : java ou C++ (avec Qt) ? Je verrais bien, je pourrais bien me lancer dans le développement de bibliothèques dynamiques gérant le jeu, et ainsi les réutiliser pour développer des GUI dans les deux langages. Enfin, ces dernières semaines, j'ai réalisé deux articles pour le prochain numéro de Linux Identity, dédié à CentOS 5.3 (j'ai d'ailleurs vu qu'un dino y participe aussi). Voilà, non je ne glande pas, non je ne suis pas mort, je n'ai juste rien de concret à présenter pour le moment !

PS : oui je sais, l'art d'écrire un billet quand on à rien à dire ... :D


Fabien (eponyme)

Utilisation des pthreads dans un object C++

Les pthreads sont fréquemment utilisés pour la programmation des threads, pour lesquels ils fournissent le nécessaire, mais aussi la protection des données. Cependant, si la bibliothèque pthread s'utilise facilement en C, il est parfois un peu difficile de faire des choses propres avec en C++. Je propose ici une solution : un objet PThread s'appuyant sur la lib pthread et fournissant les méthodes nécessaires pour l'utiliser. Cet objet nécessite qu'on lui passe, au moment où l'on souhaite threader une fonction, un pointeur sur celle-ci. Il est plus courant de créer un objet dérivant de la classe gérant le thread, et d'implémenter une méthode run(), mais j'ai préféré ce système car j'utilise cette classe dans un projet où il était plus agréable d'avoir un objet PThread, et de pouvoir lancer un thread facilement, en passant une fontion en paramètre, plutôt que de créer une nouvelle classe à chaque fois. Il est aussi possible de passer une méthode d'une autre classe en paramètre, mais il faut que celle-ci soit décalrée en static. La classe permet en plus connaitre le status du thread, de l'arreter, ou de l'attendre.

Vous trouverez un exemple dans les fichiers joints au billet. pthread.cpp et pthread.h décrivent l'objet PThread, et le main.cpp un exemple d'utilisation. N'hésitez pas à poser des questions dans les commentaires si besoins. Je sais bien que la classe est loin d'être complète, mais elle propose un bon exemple pour aborder les pthread en C++.

Pour compiler l'exécutable, dans le dossier contenant les trois fichiers sources, tapez

$ g++ -o thread main.cpp pthread.cpp -lpthread

Enfin pour l'exécuter, tapez

./thread

Vous verez cinq compteurs s'exécuter en parrallèle.


Fabien (eponyme)

Qt creator, une IDE pour Qt, par Qt

Il y avait l'Assistant, le Designer et Linguist. J'ai découvert aujourd'hui Qt Creator, un outil qui pourrait bien les rejoindre bientôt dans la suite d'outils fournis officiellement pour le développement Qt4 par trolltech. Ce dernier est une IDE, actuellement en version beta, plutôt complète, et vraiment légère. Comme d'habitude, c'est joli, ca marche bien, bref, c'est réussi.

Un serveur TCP en C, sans fork, ni threads

Il est très courant, voir systématique, dans les tutos décrivant le fonctionnement d'un serveur TCP écrit en C, de voir l'utilisation de la fonction fork() pour gérer le dialogue avec un client connecté. Des raisons bien connues font que fork() est souvent délaissé au profit d'un thread dédié à cette tâche. Sauf que la encore, ca n'est pas forcément la solution idéale. Tout d'avord, l'éternel souci du partage des ressources, mais aussi les attentions particulières qu'ils faut avoir si on arrête le serveur (et donc les processus fils), pour le relancer ensuite (dans le programme lui même, et non pas en stoppant/relançant le programme). Je propose ici une méthode différente.

xchat 2.8.6 et les balloons, fin de l'histoire

J'avais dans un ancien billet parlé du problème du temps d'apparition des balloons qui était toujours présent dans xchat 2.8.6 et proposé un patch permettant de rendre ce temps paramètrable. Ce patch a été accepté et intégré au code d'xchat dans la version CVS (voir cfgfiles.c, xchat.h et plugin-tray.c) par le développeur principal. Même si ce n'est pas grand chose, ca fait toujours plaisir de voir un petit bout de code à soi dans un logiciel qu'on utilise tous les jours. Malheureusement il faudra attendre une nouvelle release d'xchat pour avoir cette fonctionnalité utilisable sur Fedora car ce patch n'a pas été accepté pour le RPM.

C'est donc la fin de mon combat (gagné!) contre le temps fixé d'apparition des balloons !

Fabien (eponyme)

QDevelop IDE multi plateformes pour QT4

Il y a encore quelques jours, j'etais totalement indécit pour développer des interfaces graphiques entre GTK+,GTKmm (C++), wxWidgets ou QT. Je les ai tous testés (vite fait, très vite fait) et connaissais déja (assez) bien QT pour l'avoir assez longtemps utilisé. Apres réflexion, je suis resté séduit par QT, pour sa richesse (du graphique ... mais beaucoup plus : xml, bdd, reseau ... ), son designer, sa portabilité ... bref. J'ai reinstallé ce bon vieux Kdevelop sous Linux, et ai mis wxdesign (dev-cpp avec wxWidgets) sous windows que j'étais content de voir repris (et plutôt bien), et ai refais des petits tests. Puis en trainant sur des forums, j'ai découvert QDevelop, une IDE dédiée à QT4 qui offre la possibilité d'avoir une IDE identique, peut importe l'OS utilisé. Mais c'est loin d'être le seul avantage. 

Comparer deux masques en C++

Il est facile en C/C++ de savoir si une chaine correspond à un masque, surtout si celui-ci ne contient que des étoiles. On peut même d'ailleurs utiliser la fonction "fnmatch()". En revanche, comment comparer deux masques, c'est à dire savoir s'ils recouvrent le même type de chaîne ? Par exemple, eponyme*toto correspond il avec *toto  (utile pour comparer un masque de user IRC par rapport à un masque de ban) ? Le problème semblait difficile, et c'est "bigbourin" qui en quelques dizaines de minutes à pondu le code :

int masksMatch(char*str1,char*str2)
{  if (*str1 == 0 && *str2 == 0)
    return (1);
  if (*str1 == '*')
    {
      if (*str2 == 0)
      return (masksMatch(str1 + 1, str2));
      else
      return (masksMatch(str1 + 1, str2) || masksMatch(str1, str2 + 1));
    }
  if (*str2 == '*')
    {
      if (*str1 == 0)
      return (masksMatch(str1, str2 + 1));
      else
      return (masksMatch(str1 + 1, str2) || masksMatch(str1, str2 + 1));
    }
  if (*str1 == *str2)
    return (masksMatch(str1 + 1, str2 + 1));
  return (0);
}

La fonction renverra '1' si le masque str1 correspond au masque str2.

Bravo et merci à 'bigbourin'.

Fabien

Livre : Bien développer pour le Web 2.0 - Les exemples

Dans mon billet précédent, je parlais du livre "Bien développer pour le Web 2.0". Dans ce livre sont donnés quelques exemples illustrant les possibilités du web 2.0, mais sont codés en ruby. Comme exercice perso, et pour ceux qui préferent, j'ai donc repris quasiement tous les exemples et les ai portés en PHP. J'en fait le descriptif dans ce billet et donne les sources de chaque exemple en pièce jointe du billet. L'url directe de tous les exemples est : http://nicoleau-fabien.net/web2-0/