<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Eolya Consulting &#187; Technique</title>
	<atom:link href="http://www.eolya.fr/category/technique/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.eolya.fr</link>
	<description>Moteurs de recherche d&#039;entreprise et verticaux</description>
	<lastBuildDate>Thu, 24 Nov 2011 10:52:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Mercurial et Bitbucket &#8211; Workflow default &amp; stable</title>
		<link>http://www.eolya.fr/2011/11/20/mercurial-et-bitbucket-workflow-default-stable/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mercurial-et-bitbucket-workflow-default-stable</link>
		<comments>http://www.eolya.fr/2011/11/20/mercurial-et-bitbucket-workflow-default-stable/#comments</comments>
		<pubDate>Sun, 20 Nov 2011 22:29:54 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Productivité]]></category>
		<category><![CDATA[Technique]]></category>
		<category><![CDATA[Bitbucket]]></category>
		<category><![CDATA[mercurial]]></category>

		<guid isPermaLink="false">http://www.eolya.fr/?p=1189</guid>
		<description><![CDATA[Ce document est un mémento des commandes et de leurs enchainements lors de l&#8217;utilisation d&#8217;un dépôt local et d&#8217;un dépôt central hébergé sur Bitbucket. Le principe de travail est basé sur un fonctionnement avec 2 branches : default et stable. La branche &#171;&#160;default&#160;&#187; est la branche de développement qui est toujours la plus à jour [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zoonix.fr/uploads/2011/01/mercurial-logo.png"><img class="alignleft size-full wp-image-689" title="logo_small" src="http://www.zoonix.fr/uploads/2011/01/mercurial-logo.png" alt="" /></a>Ce document est un mémento des commandes et de leurs enchainements lors de l&#8217;utilisation d&#8217;un dépôt local et d&#8217;un dépôt central hébergé sur Bitbucket. Le principe de travail est basé sur un fonctionnement avec 2 branches : default et stable.</p>
<p>La branche &laquo;&nbsp;default&nbsp;&raquo; est la branche de développement qui est toujours la plus à jour (HEAD dans le monde svn).</p>
<p>La branche &laquo;&nbsp;stable&nbsp;&raquo; est la branche contenant uniquement des versions stables. Le contenu de la branche &laquo;&nbsp;stable&nbsp;&raquo; correspond à la dernière release officielle. On utilise cette branche pour la correction de bugs urgents (hotfix).</p>
<p>Les actions Mercurial sont réalisées au moyen de la commande &laquo;&nbsp;hg&nbsp;&raquo;. Certaines actions concernent le dépôt local (interactions entre les sources et le dépôt local),  d&#8217;autres concernent le dépôt central (interactions entre le dépôt local et le dépôt central). Les commandes locales seront indiquées en bleu et les autres en rouge.</p>
<p>Pour l&#8217;exemple, le projet s&#8217;appelle &laquo;&nbsp;HelloWorld&nbsp;&raquo;. Le but est de commencer avec les 2 dépôt (local et central) synchronisés.</p>
<p><strong><span style="text-decoration: underline;">Cas 1 : le projet est totalement nouveau, il n&#8217;y a ni dépôt local, ni dépôt central</span></strong></p>
<p>Créer un dépôts &laquo;&nbsp;HelloWord&nbsp;&raquo; central sur Bitbucket</p>
<p>On obtient l&#8217;url d&#8217;accès au dépot : ssh://hg@bitbucket.org/bejean/helloworld</p>
<p>Créer un dépôt local</p>
<pre>$ mkdir /Projects/HelloWord
$ cd /Projects/HelloWord
$ <span style="color: #0000ff;">hg init</span></pre>
<p><span style="text-decoration: underline;"><strong>Cas 2 : le projet existe dans un dépôt central</strong></span></p>
<p>Créer un dépôt local et récupérer les sources du dépot central.</p>
<pre>$ mkdir /Projects/HelloWord
$ cd /Projects/HelloWord
$ <span style="color: #0000ff;">hg init</span></pre>
<pre>$ hg clone ssh://hg@bitbucket.org/bejean/helloworld</pre>
<p>(cette commande met à jour à la fois le dépôt local et les sources, elle devrait être bleue et rouge)</p>
<p><span style="text-decoration: underline;"><strong>Cas 3 : le projet existe dans un dépôt local</strong></span></p>
<p>Créer un dépôt central.<br />
On obtient l&#8217;url d&#8217;accès au dépôt : ssh://hg@bitbucket.org/bejean/helloworld</p>
<p>Se placer dans le dépôt local et envoyer les sources dans le dépôt central.</p>
<pre>$ cd /Projects/HelloWord
$ <span style="color: #ff0000;">hg push ssh://hg@bitbucket.org/bejean/helloworld</span></pre>
<p>Pour la suite de cet article, nous supposons que l&#8217;on est dans le cas 1. On a alors nos dépôts créés mais vides.</p>
<p><span style="text-decoration: underline;"><strong>Configuration</strong></span></p>
<p>Afin de ne pas devoir spécifier l&#8217;url du dépôt central pour toutes les commandes qui interagissent entre le dépôt local et le dépôt central (en rouge), nous allons commencer par configurer notre dépôt local.</p>
<p>On édite le fichier &laquo;&nbsp;hgrc&nbsp;&raquo; du dépôt.</p>
<pre>$ cd /Projects/HelloWord
$ vi .hg/hgrc</pre>
<p>et on ajoute la section suivante :</p>
<pre>[paths]
default = ssh://hg@bitbucket.org/bejean/helloworld</pre>
<p><span style="text-decoration: underline;"><strong>Début de développement</strong></span></p>
<p>Commençons à travailler dans notre environnent local. On créer un fichier en local</p>
<pre>$ cd /Projects/HelloWord
$ touch readme.txt</pre>
<p>hg status indique que le fichier est inconnu dans le dépôt local</p>
<pre>$ <span style="color: #0000ff;">hg status</span>
? readme.txt</pre>
<p>On ajoute le fichier dans le dépôt local</p>
<pre>$ <span style="color: #0000ff;">hg add readme.txt</span></pre>
<p>hg status indique que le fichier est connu dans le dépôt local mais pas à jour</p>
<pre>$ <span style="color: #0000ff;">hg status</span>
A readme.txt</pre>
<p>On met a jour le fichier dans le dépôt local</p>
<pre>$ <span style="color: #0000ff;">hg commit -m "Premiere version du fichier" readme.txt</span></pre>
<p>hg status n&#8217;indique plus de fichier inconnus ou non à jour.</p>
<p>hg branches indique maintenant qu&#8217;il existe une branche &laquo;&nbsp;default&nbsp;&raquo;</p>
<pre>$ <span style="color: #0000ff;">hg branches</span>
default                        0:621365c7850a</pre>
<p>Le dépôt central n&#8217;est toujours pas au courant du contenu du dépôt local. On envoi nos modifications dans le dépôt central.</p>
<pre>$ <span style="color: #ff0000;">hg push</span>
pushing to ssh://hg@bitbucket.org/bejean/helloworld
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
remote: bb/acl: bejean is allowed. accepted payload.</pre>
<p>La copie d&#8217;écran si dessous montre que le dépot central est à jour avec une branche &laquo;&nbsp;default&nbsp;&raquo;</p>
<p><a href="http://www.eolya.fr/wp-content/uploads/2011/11/bitbucket_1.png"><img class="aligncenter size-full wp-image-1193" title="bitbucket_1" src="http://www.eolya.fr/wp-content/uploads/2011/11/bitbucket_1.png" alt="" width="511" height="229" /></a></p>
<p><span style="text-decoration: underline;"><strong>Publication d&#8217;une première version stable (v1.0) : branches et tags</strong></span></p>
<p>On considère que cette version des sources du projet est la première version stable. Il faut donc maintenant :</p>
<p>1/ tagger la version</p>
<pre>$ <span style="color: #0000ff;">hg tag v1.0</span></pre>
<p>2/ créer une branche &laquo;&nbsp;stable&nbsp;&raquo; qui soit le reflet de la branche &laquo;&nbsp;default&nbsp;&raquo;</p>
<pre>$ <span style="color: #0000ff;">hg branch stable</span>
$ <span style="color: #0000ff;">hg commit -m "branch stable"</span></pre>
<p>Afficher les tags, les branches et la branche active.</p>
<pre>$ <span style="color: #0000ff;">hg tags</span>
tip                                2:88b63958bb97
v1.0                               0:621365c7850a</pre>
<pre>$ <span style="color: #0000ff;">hg branches</span>
stable                         2:88b63958bb97
default                        1:6d1c947c8a95 (inactive)</pre>
<pre>$ <span style="color: #0000ff;">hg branch</span>
stable</pre>
<p>On met à jour le dépôt central avec la nouvelle branche.</p>
<pre>$ <span style="color: #ff0000;">hg push --new-branch</span></pre>
<p>Voici un schéma qui récapitule les différentes actions et les différents flux.</p>
<p><a href="http://www.eolya.fr/wp-content/uploads/2011/11/graph_1.png"><img class="aligncenter size-full wp-image-1212" title="graph_1" src="http://www.eolya.fr/wp-content/uploads/2011/11/graph_1.png" alt="" width="519" height="375" /></a></p>
<p>Attention, à cette étape, la branche active est &laquo;&nbsp;stable&nbsp;&raquo;. Il faut revenir à la branche &laquo;&nbsp;default&nbsp;&raquo;, pour coder de nouvelles fonctionnalités.</p>
<pre>$ <span style="color: #0000ff;">hg update default</span>
$ <span style="color: #0000ff;">hg branch</span>
default</pre>
<p><span style="text-decoration: underline;"><strong>Le développement continu &#8230;</strong></span></p>
<p>On modifie le fichier readme.txt et la commande hg status nous le confirme.</p>
<pre>$ <span style="color: #0000ff;">hg status</span>
M readme.txt</pre>
<p>on commit les modifications dans le dépôt local</p>
<pre>$ <span style="color: #0000ff;">hg commit -m "Ajout d'une fonction"</span></pre>
<p>On peut vérifier les modifications locales transférables dans le dépôt central.</p>
<pre>$ <span style="color: #ff0000;">hg outgoing</span>
comparaison avec ssh://hg@bitbucket.org/bejean/helloworld
searching for changes
changeset:   3:2b9ef639a08b
tag:         tip
parent:      1:6d1c947c8a95
user:        Dominique Bejean &lt;dominique.bejean@eolya.fr&gt;
date:        Sat Nov 19 20:16:49 2011 +0100
summary:     Ajout d'une fonction</pre>
<p>Si ces modifications sont terminées, on peut les mettre à disposition des autres développeurs dans le dépôt central</p>
<pre>$ <span style="color: #ff0000;">hg push</span></pre>
<p>De même on peut vérifier les modifications faites dans le dépôt central (par d&#8217;autres développeurs) et pouvant être récurées. Dans notre cas, il n&#8217;y en a pas.</p>
<pre>$ <span style="color: #ff0000;">hg incoming</span>
comparaison avec ssh://hg@bitbucket.org/bejean/helloworld
searching for changes
aucun changement trouvé</pre>
<p>Régulièrement, on récupère dans notre dépôt local les modifications faites par les autres développeurs et disponibles dans le dépôt central.</p>
<pre>$ <span style="color: #ff0000;">hg pull</span>
$ <span style="color: #0000ff;">hg update</span></pre>
<p><span style="text-decoration: underline;"><strong>Publication d&#8217;un nouvelle version (v2.0)</strong></span></p>
<p>La publication d&#8217;une nouvelle version implique de :</p>
<p>1/ tagger la branche active (default)</p>
<pre>$ <span style="color: #0000ff;">hg tag v2.0</span></pre>
<p>2/ mettre à jour la stable (merger default dans stable)</p>
<pre>$ <span style="color: #0000ff;">hg update stable</span>
$ <span style="color: #0000ff;">hg merge default</span></pre>
<p>(gérer les conflits. il ne devrait pas y en avoir si les hotfixs fait dans stable ont systématiquement été mergés dans default)</p>
<pre>$ <span style="color: #0000ff;">hg commit -m "merge from default"</span></pre>
<p>3/ revenir dans la branche de développement</p>
<pre>$ <span style="color: #0000ff;">hg update default</span></pre>
<p><span style="color: #000000;">Le diagramme suivant illustre les séquences de commandes durant le cycle de production d&#8217;une nouvelle version :</span></p>
<p><span style="color: #0000ff;"><a href="http://www.eolya.fr/wp-content/uploads/2011/11/graph_3.png"><img class="aligncenter size-full wp-image-1238" title="graph_3" src="http://www.eolya.fr/wp-content/uploads/2011/11/graph_3.png" alt="" width="552" height="620" /></a></span></p>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;"><strong>Correction d&#8217;un bug dans la version stable</strong></span></p>
<p>1/ se placer dans la version stable</p>
<pre>$ <span style="color: #0000ff;">hg update stable</span></pre>
<p>2/ corriger le bug</p>
<pre>$ vi readme.txt</pre>
<p>3/ commiter la correction</p>
<pre>$ <span style="color: #0000ff;">hg commit -m "v2.0 fixe"</span></pre>
<p>4/ revenir à la branche default</p>
<pre>$ <span style="color: #0000ff;">hg update default</span></pre>
<p>5/ merger la correction de la branche stable et résoudre les potentiels conflits</p>
<pre>$ <span style="color: #0000ff;">hg merge stable</span>
$ vi readme.txt
$ <span style="color: #0000ff;">hg resolve -m readme.txt</span>
$ <span style="color: #0000ff;">hg commit -m "merge resolve"</span>
$ rm readme.txt.orig</pre>
<p>&nbsp;</p>
<p>Comme référence, on trouve les 2 diagrammes suivants sur le site <a href="http://ivy.fr/" target="_blank">ivy.fr</a> (licence Creative Commons Attribution 3.0 Unported).</p>
<pre><a href="http://www.eolya.fr/wp-content/uploads/2011/11/Mercurial-QuickStart-v1.0-120dpi.png"><img class="aligncenter size-full wp-image-1219" title="Mercurial-QuickStart-v1.0-120dpi" src="http://www.eolya.fr/wp-content/uploads/2011/11/Mercurial-QuickStart-v1.0-120dpi.png" alt="" width="528" height="408" /></a></pre>
<pre><a href="http://www.eolya.fr/wp-content/uploads/2011/11/Mercurial-Usage-v1.0-120dpi.png"><img class="aligncenter size-full wp-image-1220" title="Mercurial-Usage-v1.0-120dpi" src="http://www.eolya.fr/wp-content/uploads/2011/11/Mercurial-Usage-v1.0-120dpi.png" alt="" width="528" height="408" /></a></pre>
<p>Un autre diagramme (trouvé sur le site <a href="http://secretgeek.net/mercurial_flow.asp" target="_blank">secretGeek</a>) qui indique un workflow basic. Le point 6 (qui n&#8217;est pas systématique) doit être suivi d&#8217;un &laquo;&nbsp;hg up&nbsp;&raquo;.</p>
<p><a href="http://www.eolya.fr/wp-content/uploads/2011/11/mercurial_workflow_image.png"><img class="aligncenter size-full wp-image-1224" title="mercurial_workflow_image" src="http://www.eolya.fr/wp-content/uploads/2011/11/mercurial_workflow_image.png" alt="" width="459" height="374" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.eolya.fr/2011/11/20/mercurial-et-bitbucket-workflow-default-stable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git et Subversion : quand plus rien ne va</title>
		<link>http://www.eolya.fr/2011/09/17/git-et-subversion-quand-plus-rien-ne-va/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=git-et-subversion-quand-plus-rien-ne-va</link>
		<comments>http://www.eolya.fr/2011/09/17/git-et-subversion-quand-plus-rien-ne-va/#comments</comments>
		<pubDate>Sat, 17 Sep 2011 17:00:43 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Productivité]]></category>
		<category><![CDATA[Technique]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://www.eolya.fr/?p=1103</guid>
		<description><![CDATA[Les plugins WordPress sont livrés dans le directory WordPress au moyen d&#8217;un repository SVN. A chaque nouvelle version du plugin, on en commit les sources et on les tags, ce qui provoque l’apparition de la nouvelle version sur le site WordPress. Afin de gérer les sources du plugin et de travailler en équipe, on peut [...]]]></description>
			<content:encoded><![CDATA[<p>Les plugins WordPress sont livrés dans le <a href="http://wordpress.org/extend/plugins/" target="_blank">directory WordPress</a> au moyen d&#8217;un repository <a href="http://subversion.apache.org/" target="_blank">SVN</a>. A chaque nouvelle version du plugin, on en commit les sources et on les tags, ce qui provoque l’apparition de la nouvelle version sur le site WordPress.</p>
<p>Afin de gérer les sources du plugin et de travailler en équipe, on peut utiliser un outil de gestion de source tel que <a href="http://git-scm.com/">Git</a> et utiliser <a href="https://github.com/">Github</a> comme repository central. Pour la passerelle Git vers SVN, on utilise alors la commande <strong>git svn</strong> et ses différentes actions.</p>
<p>Je ne décrirai pas ici comment fonction SVN et Git. Par contre, je souhaite expliquer comment j&#8217;ai pu résoudre un problème de mise à jour du repository SVN de WordPress lors de la livraison d&#8217;une nouvelle version d&#8217;un plugin.</p>
<p>Donc, après des modifications du plugin, je commit et je mets à jours github. Les commandes successives sont en simplifiant :</p>
<pre>git commit ...
git push origin master</pre>
<p>&nbsp;</p>
<p>Jusque là tout va bien !</p>
<p>Après ceci, je veux mettre à jour le repoitory svn de WordPress puis tagger une nouvelle version du plugin et là patatra !</p>
<pre>git svn dcommit
    Committing to http://plugins.svn.wordpress.org/browse-content-by-my-solr-server/trunk ...
    Merge conflict during commit: File or directory 'browse-content-by-my-solr-server.php' is
    out of date; try updating: resource out of date; try updating at
    /usr/local/git/libexec/git-core/git-svn line 579</pre>
<p>&nbsp;</p>
<p>Que ce fichier soit &laquo;&nbsp;out of date&nbsp;&raquo;, je n&#8217;en doute pas car je l&#8217;ai bien modifié en local et après avoir mis à jour le repository github, c&#8217;est le repository SVN que je veux mettre à jour avec la commande &laquo;&nbsp;git svn dcommit&nbsp;&raquo; . J&#8217;ai l&#8217;impression que j&#8217;ai manqué quelque chose comme une opération &laquo;&nbsp;pull&nbsp;&raquo; en provenance de SVN et d&#8217;un &laquo;&nbsp;rebase&nbsp;&raquo; dans la foulée. Mais, étant le seul à travailler sur ce plugin, personne d&#8217;autre n&#8217;a fait évoluer le repository SVN parallèlement à mes modifications locales. Mystère !</p>
<p>Après de longues recherches sur cette erreur et aucune solution qui ne me permette de commiter et tagger dans svn, je trouve cet article qui me permet de repartir de zéro: <a href="http://danielbachhuber.com/2010/09/29/how-to-properly-use-git-with-wordpress-org-subversion/" target="_blank">http://danielbachhuber.com/2010/09/29/how-to-properly-use-git-with-wordpress-org-subversion/</a></p>
<p>La manipulation décrite rétablie le répertoire de travail local avec le contenu du SVN WordPress qui contient toujours la version précédente du plugin, puis, réinjecte les modifications qui sont dans le repository sur github. En gros, les étapes sont :</p>
<ol>
<li>sauvegarder les derniers developpements locaux (tar &#8230;) et mettre tout cela de coter au cas où &#8230;</li>
<li>recloner le repository svn en local dans un répertoire travail vierge</li>
<li>récupérer la dernière version github qui est à jour avec les dernières modifications (mais sauvegardées par ailleurs au cas où)</li>
<li>commiter sous svn et tagger</li>
</ol>
<p>&nbsp;</p>
<p>Et dans la pratique, cela donne :</p>
<p>* Recréer le répertoire local de travail</p>
<pre>cd &lt;wordpress plugin dir&gt;
rm -rf browse-content-by-my-solr-server
mkdir browse-content-by-my-solr-server</pre>
<p>&nbsp;</p>
<p>* Récupérer dans SVN le numéro de révision correspondant au dernier commit fait.</p>
<pre>svn log https://plugins.svn.wordpress.org/browse-content-by-my-solr-server/</pre>
<pre>------------------------------------------------------------------------
 r436435 | dbejean | 2011-09-11 20:06:54 +0200 (Dim, 11 sep 2011) | 1 line</pre>
<pre>Create tag 1.1.0
 ------------------------------------------------------------------------
 r436432 | dbejean | 2011-09-11 19:58:50 +0200 (Dim, 11 sep 2011) | 1 line</pre>
<pre>template 3
...</pre>
<p>On ne retient pas r436435 qui a été créé par une commande &laquo;&nbsp;git svn tag&nbsp;&raquo;, mais r436432.</p>
<p>&nbsp;</p>
<p>* Cloner le repository SVN dans le répertoire local de travail :</p>
<pre>git svn clone -s -r436432 https://plugins.svn.wordpress.org/browse-content-by-my-solr-server/
cd browse-content-by-my-solr-server
git svn fetch</pre>
<p>Note : &laquo;&nbsp;-s&nbsp;&raquo; est un raccourci pour   &laquo;&nbsp;-t tags -b branches -T trunk&nbsp;&raquo;</p>
<p>&nbsp;</p>
<p>* Ré-associer le répertoire local de travail au repository Github</p>
<pre>git remote add -f origin git@github.com:bejean/browse-content-by-my-solr-server.git
git checkout origin/master *
git add *
git commit -m "Updated from GitHub"</pre>
<p>&nbsp;</p>
<p>* Commiter et tagguer la nouvelle version du plugin dans le SVN WordPress</p>
<pre>git svn rebase
git svn dcommit
git svn tag "x.x.x"</pre>
<p>&nbsp;</p>
<p>Et voilà le plugin est livré !</p>
<p>Il ne me reste plus qu&#8217;à trouver ce qui a provoqué cette erreur afin quelle ne se reproduise plus.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.eolya.fr/2011/09/17/git-et-subversion-quand-plus-rien-ne-va/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Obtenir une compilation nocturne de Solr 3.1 ou Solr 4.0</title>
		<link>http://www.eolya.fr/2010/11/03/obtenir-une-compilation-nocturne-de-lucene-4-0-et-solr-4-0/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=obtenir-une-compilation-nocturne-de-lucene-4-0-et-solr-4-0</link>
		<comments>http://www.eolya.fr/2010/11/03/obtenir-une-compilation-nocturne-de-lucene-4-0-et-solr-4-0/#comments</comments>
		<pubDate>Wed, 03 Nov 2010 18:11:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Lucene / Solr]]></category>
		<category><![CDATA[Moteur de recherche]]></category>
		<category><![CDATA[Technique]]></category>
		<category><![CDATA[nightly build]]></category>
		<category><![CDATA[Solr]]></category>

		<guid isPermaLink="false">http://www.zoonix.fr/?p=710</guid>
		<description><![CDATA[Depuis le début de l&#8217;année les sources de Lucene et Solr ont fusionnées. La prochaine version commune aura pour numéro 4.0. Pour ceux qui veulent déjà tester la version en cours de développement, il faut en récupérer les sources et les compiler (java 1.6 requis). En effet, les liens de téléchargement des compilations nocturnes ne [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zoonix.fr/uploads/2010/03/solr.jpg"><img class="alignleft size-full wp-image-477" title="solr" src="http://www.zoonix.fr/uploads/2010/03/solr.jpg" alt="solr" width="105" height="75" /></a>Depuis le début de l&#8217;année les sources de Lucene et Solr ont fusionnées. La prochaine version commune aura pour numéro 4.0. Pour ceux qui veulent déjà tester la version en cours de développement, il faut en récupérer les sources et les compiler (java 1.6 requis). En effet, les liens de téléchargement des compilations nocturnes ne fonctionnent pas. En prérequis, il faut disposer de <strong>svn</strong> client et de <strong>ant</strong>.</p>
<p>Il existe actuellement 2 versions en cours de développement : Solr 3.1 et Solr 4.0. Ma compréhension est que :</p>
<ul>
<li>Solr 3.1 est une version plutôt stable qui devrait la prochaine version de Solr et embarquent Lucene 3.1. Sortie possible : mars ou avril 2011.</li>
<li>Solr 4.0 est la version de développement (trunk) moins stable et dont le disponibilité dervait être pour 2012.</li>
</ul>
<p>Pour une explication sur ces 2 versions des sources de Solr, lire ce message de <strong>Uwe Schindler</strong> : <a href="http://lucene.472066.n3.nabble.com/Lucene-3-x-branch-created-td777485.html" target="_blank">Lucene 3.x branch created</a> et cette discussion : <a href="http://lucene.472066.n3.nabble.com/Solr-3-1-td1522319.html" target="_blank">Solr 3.1</a><span id="more-710"></span></p>
<h3>Solr 3.1</h3>
<p>Créer un répertoire de travail :</p>
<pre>mkdir ~/solr-3.1</pre>
<p>Se placer dans ce répertoire et récupérer les sources :</p>
<pre>cd ~/solr-3.1
svn co http://svn.apache.org/repos/asf/lucene/dev/branches/branch_3x</pre>
<p>Compiler les sources :</p>
<pre>cd ~/solr-3.1/branch_3x/lucene
ant dist
cd ~/solr-3.1/branch_3x/solr
ant dist</pre>
<p>La javadoc est disponible ici : <a href="https://hudson.apache.org/hudson/job/Lucene-3.x/javadoc/all/index.html" target="_blank">https://hudson.apache.org/hudson/job/Lucene-3.x/javadoc/all/index.html</a></p>
<h3>Solr 4.0</h3>
<p>Créer un répertoire de travail :</p>
<pre>mkdir ~/solr-4.0</pre>
<p>Se placer dans ce répertoire et récupérer les sources :</p>
<pre>cd ~/solr-4.0
svn co http://svn.apache.org/repos/asf/lucene/dev/trunk</pre>
<p>Compiler les sources :</p>
<pre>cd ~/solr-4.0/trunk/modules
ant compile
cd ~/solr-4.0/trunk/lucene
ant dist
cd ~/solr-4.0/trunk/solr
ant dist</pre>
<p>La javadoc est disponible ici : <a href="https://hudson.apache.org/hudson/job/Lucene-3.x/javadoc/all/index.html" target="_blank">https://hudson.apache.org/hudson/job/Lucene-trunk/javadoc/all/index.html</a></p>
<h3>Note du 2/11/2011 :</h3>
<p>Le meilleur endroit pour récupérer les builds nocturnes ainsi que les liens vers les javadoc est : <a href="http://wiki.apache.org/solr/NightlyBuilds">http://wiki.apache.org/solr/NightlyBuilds</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.eolya.fr/2010/11/03/obtenir-une-compilation-nocturne-de-lucene-4-0-et-solr-4-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installation de Munin sur Debian Lenny</title>
		<link>http://www.eolya.fr/2010/10/12/installation-de-munin-sur-debian-lenny/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=installation-de-munin-sur-debian-lenny</link>
		<comments>http://www.eolya.fr/2010/10/12/installation-de-munin-sur-debian-lenny/#comments</comments>
		<pubDate>Tue, 12 Oct 2010 14:52:06 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Technique]]></category>

		<guid isPermaLink="false">http://www.zoonix.fr/?p=655</guid>
		<description><![CDATA[Cet article d&#233;crit l&#39;installation de base du moniteur de ressources Numin, puis fourni un lien sur un article d&#233;crivant comment ajouter un plugin pour le monitoring des vhosts apache. Activation des modules apache : sudo a2enmod status sudo a2enmod info Installation de Munin (voir&#160;http://www.howtoforge.com/server-monitoring-with-munin-and-monit-on-debian-lenny) : sudo apt-get install munin munin-node libwww-perl vi /etc/munin/munin.conf pour modifier [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zoonix.fr/uploads/2010/10/munin.png"><img alt="" class="alignleft size-full wp-image-663" src="http://www.zoonix.fr/uploads/2010/10/munin.png" style="width: 121px; height: 30px;" title="munin" /></a>Cet article d&eacute;crit l&#39;installation de base du moniteur de ressources Numin, puis fourni un lien sur un article d&eacute;crivant comment ajouter un plugin pour le monitoring des vhosts apache.<span id="more-655"></span></p>
<h4>Activation des modules apache :</h4>
<pre>sudo a2enmod status
sudo a2enmod info</pre>
<h4>Installation de Munin (voir&nbsp;http://www.howtoforge.com/server-monitoring-with-munin-and-monit-on-debian-lenny) :</h4>
<pre>sudo apt-get install munin munin-node libwww-perl
vi /etc/munin/munin.conf pour modifier [localhost.localdomain]
sudo /etc/init.d/munin-node restart
</pre>
<h4>Activation de plugin Munin qui ne le sont pas par d&eacute;faut (http://www.crashdump.fr/tutoriels/munin-le-top-du-monitoring-3/) :</h4>
<pre>sudo ln -s /usr/share/munin/plugins/apache_accesses /etc/munin/plugins/
sudo ln -s /usr/share/munin/plugins/apache_processes /etc/munin/plugins/
sudo ln -s /usr/share/munin/plugins/apache_volume /etc/munin/plugins/
sudo ln -s /usr/share/munin/plugins/netstat /etc/munin/plugins/netstat
sudo ln -s /usr/share/munin/plugins/uptime /etc/munin/plugins/uptime</pre>
<h4>Modification des droits pour le plugin netstat :</h4>
<p>Cr&eacute;er le fichier&nbsp;/etc/munin/plugin-conf.d/netstat</p>
<pre>sudo vi /etc/munin/plugin-conf.d/netstat</pre>
<p>avec le contenu suivant</p>
<pre>[netstat]
user root</pre>
<h4>Pour le monitoring des vhost apache :</h4>
<p><a href="http://stubbedtoe.co.nz/index.php/2009/09/apache-vhost-monitoring-with-munin/">http://stubbedtoe.co.nz/index.php/2009/09/apache-vhost-monitoring-with-munin/</a></p>
<h4>Un plugin fail2ban :</h4>
<p><a href="http://www.majorxtrem.be/2009/08/14/plugins-fail2ban-pour-munin/" target="_blank">http://www.majorxtrem.be/2009/08/14/plugins-fail2ban-pour-munin/</a></p>
<p>Penser &agrave; ajouter le droit d&#39;ex&eacute;cution sur le plugin</p>
<pre>sudo chmod +x /usr/share/munin/plugins/fail2ban
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.eolya.fr/2010/10/12/installation-de-munin-sur-debian-lenny/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installer Atlassian Jira 4.1 et Confluence 3.3 sur Debian Lenny avec Tomcat 5.5 et MySQL</title>
		<link>http://www.eolya.fr/2010/10/11/installer-atlassian-jira-4-1-et-confluence-3-3-sur-debian-lenny-avec-tomcat-5-5-et-mysql/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=installer-atlassian-jira-4-1-et-confluence-3-3-sur-debian-lenny-avec-tomcat-5-5-et-mysql</link>
		<comments>http://www.eolya.fr/2010/10/11/installer-atlassian-jira-4-1-et-confluence-3-3-sur-debian-lenny-avec-tomcat-5-5-et-mysql/#comments</comments>
		<pubDate>Mon, 11 Oct 2010 08:38:29 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Technique]]></category>

		<guid isPermaLink="false">http://www.zoonix.fr/?p=629</guid>
		<description><![CDATA[Cet article est un r&#233;sum&#233; des proc&#233;dures d&#39;installation de Jira et Confluence telle qu&#39;on peut les trouver sur le site de Atlassian. Il est focalis&#233; sur un environnement Tomcat 5.5 et MySQL. Pre-requis Il s&#39;agit des pre-requis consolid&#233;s pour Jira et Confluence, notament pour la configuration de Tomcat qui n&#233;cessite quelques ajustements. Avoir JDK 6 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zoonix.fr/uploads/2010/10/logo_atlassian1.png"><img alt="" border="0" class="alignleft size-full wp-image-652" src="http://www.zoonix.fr/uploads/2010/10/logo_atlassian1.png" style="width: 130px; height: 30px;" title="logo_atlassian1" /></a>Cet article est un r&eacute;sum&eacute; des proc&eacute;dures d&#39;installation de Jira et Confluence telle qu&#39;on peut les trouver sur le site de <a href="http://www.atlassian.com/" target="_blank">Atlassian</a>. Il est focalis&eacute; sur un environnement Tomcat 5.5 et MySQL.<span id="more-629"></span></p>
<h3>Pre-requis</h3>
<p>Il s&#39;agit des pre-requis consolid&eacute;s pour Jira et Confluence, notament pour la configuration de Tomcat qui n&eacute;cessite quelques ajustements.</p>
<p>Avoir JDK 6 de Sun (openJDK 6 n&#39;est pas support&eacute; par Atlassian), Tomcat 5.5 et MySQL 5.x install&eacute;s.</p>
<p>Dans le fichier server.xml de Tomcat (/var/lib/tomcat5.5/conf/server.xml), ajouter le param&egrave;tre URIEncoding=&quot;UTF-8&quot; au connecteur &quot;non-SSL&quot;.</p>
<p>Dans le script de d&eacute;marrage de Tomcat (/etc/init.d/tomcat5.5), ajouter les param&egrave;tres suivants pour le d&eacute;marrage</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">if [ -z &amp;quot;$JAVA_OPTS&amp;quot; ]; then
    JAVA_OPTS=&amp;quot;-Djava.awt.headless=true -Xmx768M -Duser.timezone=Europe/Paris -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true -Dmail.mime.decodeparameters=true -XX:MaxPermSize=128m&amp;quot;
fi</pre></div></div>

<p>Dans /usr/share/tomcat5.5/common/lib, copier le fichier jar du connecteur java de MySQL disponible via cette page : <a href="http://www.mysql.com/downloads/connector/j/" target="_blank">http://www.mysql.com/downloads/connector/j/</a></p>
<h3>Jira</h3>
<p>Il s&#39;agit d&#39;installer la version EAR-WAR de Jira. La proc&eacute;dure d&#39;installation sur le site de Atlassian est &agrave; cette adresse :</p>
<p><a href="http://confluence.atlassian.com/display/JIRA/Installing+JIRA+WAR-EAR" target="_blank">http://confluence.atlassian.com/display/JIRA/Installing+JIRA+WAR-EAR</a></p>
<p>Cr&eacute;er la base de donn&eacute;e en utf-8 et donner les droits &agrave; un utilisateur.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">mysql&amp;gt; CREATE DATABASE jiradb CHARACTER SET utf8 COLLATE utf8_bin;
mysql&amp;gt; grant all privileges on jiradb.* to &amp;#39;jira&amp;#39;@&amp;#39;localhost&amp;#39; identified by &amp;#39;jira&amp;#39; with grant option;</pre></div></div>

<p>T&eacute;l&eacute;charger la distribution &agrave; l&#39;adresse suivante : <a href="http://www.atlassian.com/software/jira/JIRADownloadCenter.jspa" target="_blank">http://www.atlassian.com/software/jira/JIRADownloadCenter.jspa</a></p>
<p>Au besoin, choisir le bon OS et afficher toutes les versions disponibles (&quot;show all&quot; au dessus du bouton &quot;download&quot;)</p>
<p>Contrairement &agrave; ce que demande la documentation sur le site de Atlassian, je ne cr&eacute;er pas de d&#39;utilisateur &quot;jira&quot;. J&#39;installe Jira dans /opt/atlassian.</p>
<p>D&eacute;compresser la distribution dans /opt/atlassian et cr&eacute;er un lien symbolique</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">gunzip atlassian-jira-enterprise-4.1.2.tar.gz
tar xf atlassian-jira-enterprise-4.1.2.tar
sudo chown -R un_utilisateur: /opt/atlassian
ln -s atlassian-jira-enterprise-4.1.2 jira</pre></div></div>

<p>J&#39;indique le Jira home path dans le fichier /opt/atlassian/jira/jira/edit-webapp/WEB-INF/classes/jira-application.properties</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">jira.home = /opt/atlassian/jira</pre></div></div>

<p>Donner les droits d&#39;&eacute;criture &agrave; tout le monde dans le r&eacute;pertoires /opt/atlassian/atlassian-jira-enterprise-4.1.2, /opt/atlassian/atlassian-jira-enterprise-4.1.2/cache et /opt/atlassian/atlassian-jira-enterprise-4.1.2/plugins</p>
<p>Configurer la connexion &agrave; la base de donn&eacute;es dans le fichier /opt/atlassian/jira/jira/edit-webapp/WEB-INF/classes/entityengine.xml&nbsp;</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&amp;lt;datasource name=&amp;quot;defaultDS&amp;quot; field-type-name=&amp;quot;mysql&amp;quot;
    helper-class=&amp;quot;org.ofbiz.core.entity.GenericHelperDAO&amp;quot;
    check-on-start=&amp;quot;true&amp;quot;
    use-foreign-keys=&amp;quot;false&amp;quot;
    use-foreign-key-indices=&amp;quot;false&amp;quot;
    check-fks-on-start=&amp;quot;false&amp;quot;
    check-fk-indices-on-start=&amp;quot;false&amp;quot;
    add-missing-on-start=&amp;quot;true&amp;quot;
    check-indices-on-start=&amp;quot;true&amp;quot;&amp;gt;</pre></div></div>

<p>et v&eacute;rifier par la m&ecirc;me occasion :</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&amp;lt;transaction-factory class=&amp;quot;org.ofbiz.core.entity.transaction.JNDIFactory&amp;quot;&amp;gt;
    &amp;lt;user-transaction-jndi jndi-server-name=&amp;quot;default&amp;quot; jndi-name= &amp;quot;java:comp/env/UserTransaction&amp;quot; /&amp;gt;&amp;nbsp;
    &amp;lt;transaction-manager-jndi jndi-server-name=&amp;quot;default&amp;quot; jndi-name=&amp;quot;java:comp/env/UserTransaction&amp;quot; /&amp;gt;
&amp;lt;/transaction-factory&amp;gt;</pre></div></div>

<p>Construire Jira</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">cd /opt/atlassian/jira
./build.sh</pre></div></div>

<p>Ajouter dans /usr/share/tomcat5.5/common/lib les librairies n&eacute;cessaires &agrave; jira et qui se trouvent sur le site Atlassian &agrave; l&#39;adresse : <a href="http://confluence.atlassian.com/download/attachments/200709089/jira-jars-tomcat5.zip?version=1&amp;modificationDate=1252474277460" target="_blank">http://confluence.atlassian.com/download/attachments/200709089/jira-jars-tomcat5.zip?version=1&amp;modificationDate=1252474277460</a></p>
<p>Stopper Tomcat</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">sudo /etc/init.d/tomcat5.5 stop</pre></div></div>

<p>Copier le fichier /opt/atlassian/jira/dist-tomcat/tomcat-5.5/jira.xml dans /var/lib/tomcat5.5/conf/Catalina/localhost</p>
<p>D&eacute;marrer Tomcat</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">sudo /etc/init.d/tomcat5.5 start</pre></div></div>

<h3>Confluence</h3>
<p>Cr&eacute;er la base de donn&eacute;e en utf-8 et donner les droits &agrave; un utilisateur.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">mysql&amp;gt; CREATE DATABASE confluence CHARACTER SET utf8 COLLATE utf8_bin;
mysql&amp;gt; grant all privileges on confluence.* to &amp;#39;confluence&amp;#39;@&amp;#39;localhost&amp;#39; identified by &amp;#39;confluence&amp;#39; with grant option;</pre></div></div>

<p>Il s&#39;agit de la version EAR-WAR de confluence. La proc&eacute;dure d&#39;installation sur le site de Atlassian est &agrave; cette adresse : <a href="http://confluence.atlassian.com/display/DOC/Installing+Confluence+EAR-WAR+on+Tomcat" target="_blank">http://confluence.atlassian.com/display/DOC/Installing+Confluence+EAR-WAR+on+Tomcat</a></p>
<p>T&eacute;l&eacute;charger la distribution &agrave; l&#39;adresse suivante : <a href="http://www.atlassian.com/software/confluence/ConfluenceDownloadCenter.jspa" target="_blank">http://www.atlassian.com/software/confluence/ConfluenceDownloadCenter.jspa</a></p>
<p>Au besoin, choisir le bon OS et afficher toutes les versions disponibles (&quot;show all&quot; au dessus du bouton &quot;download&quot;)</p>
<p>D&eacute;compresser l&#39;archive dans /opt/atlassian et cr&eacute;er un lien symbolique</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">gunzip confluence-3.3.3.tar.gz
tar xf confluence-3.3.3.tar
sudo chown -R un_utilisateur: /opt/atlassian
ln -s confluence-3.3.3 confluence</pre></div></div>

<p>Donner les droits d&#39;&eacute;criture &agrave; tout le monde dans le r&eacute;pertoire confluence-3.3.3</p>
<p>Editer confluence/WEB-INF/classes/confluence-init.properties afin d&#39;indiquer le Confluence home path</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">confluence.home = /opt/atlassian/confluence</pre></div></div>

<p>Cr&eacute;er un fichier confluence.xml dans le r&eacute;pertoire conf/Catalina/localhost de Tomcat qui contient :</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">&amp;lt;Context path=&amp;quot;/confluence&amp;quot; docBase=&amp;quot;/opt/atlassian/confluence/confluence&amp;quot; debug=&amp;quot;0&amp;quot; reloadable=&amp;quot;true&amp;quot; /&amp;gt;</pre></div></div>

<p>Red&eacute;marrer Tomcat</p>
<p>Se connecter &agrave; confluence pour ex&eacute;cuter le wizard : http://serveur:8180/confluence/</p>
<h3>Probl&egrave;me connu</h3>
<p>Les menus de Confluence ne fonctionnent pas ou Confluence ne d&eacute;marre pas lorsque Conflunence et Jira sont h&eacute;berg&eacute;s dans le m&ecirc;me serveur Tomcat.</p>
<p>Ces probl&egrave;mes sont du au fait que ces deux produits utilisent une version diff&eacute;rente d&#39;une m&ecirc;me librairie Atlassian. Il s&#39;agit de org.apache.felix.main-2.0.0-atlassian-1.jar pour Jira et org.apache.felix.main-2.0.4-atlassian-3.jar pour Confluence. La solution consiste a :</p>
<ul>
<li>arr&ecirc;ter Tomcat</li>
<li>sauvegarder org.apache.felix.main-2.0.0-atlassian-1.jar de Jira</li>
<li>remplacer toutes les instances de org.apache.felix.main-2.0.0-atlassian-1.jar dans Jira (il y en a 2) par org.apache.felix.main-2.0.4-atlassian-3.jar de Confluence</li>
<li>d&eacute;marrer Tomcat</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.eolya.fr/2010/10/11/installer-atlassian-jira-4-1-et-confluence-3-3-sur-debian-lenny-avec-tomcat-5-5-et-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Détection de la langue d’un texte (3)</title>
		<link>http://www.eolya.fr/2010/03/26/detection-de-la-langue-d%e2%80%99un-texte-3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=detection-de-la-langue-d%25e2%2580%2599un-texte-3</link>
		<comments>http://www.eolya.fr/2010/03/26/detection-de-la-langue-d%e2%80%99un-texte-3/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 00:17:00 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Lucene / Solr]]></category>
		<category><![CDATA[Technique]]></category>
		<category><![CDATA[n-gram]]></category>
		<category><![CDATA[ngp]]></category>
		<category><![CDATA[ngramj]]></category>

		<guid isPermaLink="false">http://www.zoonix.fr/?p=569</guid>
		<description><![CDATA[Dans un premier article sur le sujet, je décris une méthode de détection de la langue d&#8217;un texte basée sur un calcul statistique de présence de n-gram dans le texte.  Cette distribution statistique est alors comparée à des distributions types pré-calculées sur des corpus de texte dans différentes langues. La langue du texte est alors [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zoonix.fr/uploads/2010/03/java.jpg"><img class="alignleft size-full wp-image-608" title="java" src="http://www.zoonix.fr/uploads/2010/03/java.jpg" alt="java" width="78" height="124" /></a>Dans <a href="http://www.zoonix.fr/2008/02/20/detection-de-la-langue-dun-texte/">un premier article sur le sujet</a>, je décris une méthode de détection de la langue d&#8217;un texte basée sur un calcul statistique de présence de n-gram dans le texte.  Cette distribution statistique est alors comparée à des distributions types pré-calculées sur des corpus de texte dans différentes langues. La langue du texte est alors à priori celle du corpus présentant la distribution la plus proche. Comme je l&#8217;ai expliqué dans mon premier article, j’ai utilisé <a onclick="javascript:pageTracker._trackPageview('/outbound/article/ngramj.sourceforge.net');" href="http://ngramj.sourceforge.net/" target="_blank">NgramJ</a>,  une librairie Java open source. Après différents tests avec d&#8217;autres librairies, NgramJ reste pour moi la plus efficace.</p>
<p>Cependant, cette méthode n&#8217;est pas fiable à 100% et <strong>NgramJ</strong> est limitée  dans sa version actuelle à 26 langues détectables : Bulgare (bg), Tchèque (cz), Danois (da), Allemand (de), Grec (el), Anglais (en) Espagnol (es), Estonien (et), Finlandais (fi), Français (fr), Hongrois (hu), Islandais (is), Italien (it), Lituanien (lt), Letton (lv), Maltais (mt) , Néerlandais (nl), Norvégien (no), Polonais (pl), Portugais (pt), Roumain (ro), Russe (ru) , Slovaque (sk), Slovène (sl), Suédois (sv) et Thaï (th).</p>
<p>Je voudrais proposer 2 pistes pour améliorer NGramJ : la fiabilité de la détection et le nombre de langues détectables.<span id="more-569"></span></p>
<h3>La fiabilité de la détection</h3>
<p><strong>NgramJ</strong> utilise un algorithme complexe de calcul statistique sur les n-grams et je n&#8217;ai pas la prétention de l&#8217;améliorer. Par contre, on peut facilement fournir des informations complémentaire à <strong>NGramJ</strong> afin qu&#8217;il oriente sa détection sur un sous-ensemble restreint de langues et non pas sur toutes les langues qu&#8217;il gère (surtout si on veut en augmenter le nombre).</p>
<p>Que connait-on du texte que l&#8217;on veut analyser ? On connait l&#8217;encodage de ses caractères (iso-8859-1, iso-8859-5, windows-1252, &#8230; et souvent unicode ou utf-8). Chacun de ces jeux de caractères permet d&#8217;écrire un ensemble plus ou moins important de langues (voir <a href="http://en.wikipedia.org/wiki/Character_encoding" target="_blank">Character encoding</a>). Unicode est particulier car il permet de coder toutes les langues, par contre une ou plusieurs langues partagent un sous ensemble d&#8217;unicode qu&#8217;il est facile d&#8217;identifier (voir <a href="http://unicode.org/charts/" target="_blank">Unicode 5.2 Character Code Charts</a>). On peut donc pour un texte donné se limiter à la détection des langues couvertes par le sous ensemble unicode qu&#8217;il utilise.</p>
<p>Par exemple, pour un texte codé en iso-8859-5 (caractères cyrilliques) les langues possibles sont : Bulgare (bg), Biélorusse (be), Macédonien (mk), Russe (ru), Serbe (sr) et Ukrainien (uk). La seule langue que devrait donc nous proposer <strong>NGramJ</strong> si on lui demande de se retreindre à ces langes est le Russe. Ce n&#8217;est pas satisfaisant. En effet, je ne veux pas que <strong>NgramJ</strong> me dise qu&#8217;un texte Bulgare est du Russe. Plus loin dans cet article, on verra comment &laquo;&nbsp;appendre&nbsp;&raquo; de nouvelles langues à <strong>NgramJ</strong>.</p>
<p>Encore mieux, on peut sans même le demander à <strong>NgramJ</strong> connaitre la langue d&#8217;une texte. En effet, certains jeux de caractères permettent de coder une seule langue : iso-8859-15 (Estonien), iso-8859-9 (Turc), iso-8859-7 (Grec), &#8230;</p>
<p>En conclusion, même si on parvient à apprendre à <strong>NgramJ</strong> la totalité des langues existantes (et pourquoi pas), on pourra toujours lui indiquer de travailler sur un sous-ensemble réduit de deux à une dizaine de langues en fonction de l&#8217;encodage du texte.</p>
<p>Un point auquel il faut porter attention est qu&#8217;un même jeux de caractères peut avoir plusieurs noms voisins. On trouve sur le site de l&#8217;<a href="http://www.iana.org/assignments/character-sets" target="_blank">INIA</a>, l&#8217;ensemble des jeux de caractères avec leur nom préféré et leurs alias.<br class="spacer_" /></p>
<p>Pour traiter cet aspect préliminaire à l&#8217;utilisation de NGramJ, j&#8217;ai développé une classe utilitaire <strong>CharsetLanguages</strong> qui permet de :</p>
<ul>
<li>Obtenir le nom préféré d&#8217;un jeux de caractères.</li>
<li>Obtenir les blocs unicode utilisé pour l&#8217;écriture d&#8217;un texte</li>
<li>Obtenir les langues associées à un jeu de caractères</li>
<li>Obtenir les langues associées aux blocs unicode détectés dans un texte</li>
</ul>
<p>Pour simplifier l&#8217;utilisation de <strong>NgramJ</strong>, j&#8217;ai également développé une classe <strong>LanguageRecognizerCngram</strong> qui permet de :</p>
<ul>
<li>Initialiser un contexte de détection en spécifiant le répertoire ou sont les fichiers de définitions des langues (fichiers modèles) et la liste des langues que l&#8217;on veut pouvoir détecter (si on sait à l&#8217;avance que les documents que l&#8217;on va traiter se limitent à ces langues) </li>
<li>lancer la reconnaissance d&#8217;une langue dans un texte</li>
</ul>
<p>Le code source de ces classes est fournie sous la forme d&#8217;un projet Eclipse. je fournie également la version compilée de <strong>NGramJ</strong> modifié. Ces modifications ont été transmises à l&#8217;auteur qui s&#8217;est proposé de les intégrer à la version officielle.</p>
<p>Voici un exemple de code pour l&#8217;utilisation de ces classes :</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399; font-weight: bold;">String</span> getLanguage <span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> content, <span style="color: #003399; font-weight: bold;">String</span> charSet<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #003399; font-weight: bold;">String</span> language = <span style="color: #006600; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Define the maximum length for the text to be analyzed</span>
<span style="color: #006600; font-weight: bold;">int</span> languageDetectionLength = <span style="color: #cc66cc;">2048</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Define a list of candidate languages for the text</span>
<span style="color: #003399; font-weight: bold;">String</span> languageDetectionList = <span style="color: #0000ff;">&quot;bg, ru, sr, uk&quot;</span><span style="color: #339933;">;</span>
&nbsp;
content = content.<span style="color: #006633;">substring</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #003399; font-weight: bold;">Math</span>.<span style="color: #006633;">min</span><span style="color: #009900;">&#40;</span>content.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, languageDetectionLength<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create the language detector</span>
LanguageRecognizerCngram lrCnGram = <span style="color: #000000; font-weight: bold;">new</span> LanguageRecognizerCngram<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000;  font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>lrCnGram<span style="color: #339933;">!</span>=<span style="color: #006600; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Set the directory for the language models</span>
    lrCnGram.<span style="color: #006633;">setLanguageModelsDir</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/Data/ngramj/ngp/ngp&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000;  font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>languageDetectionList<span style="color: #339933;">!</span>=<span style="color: #006600; font-weight: bold;">null</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #339933;">!</span><span style="color: #0000ff;">&quot;&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>languageDetectionList<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Create a list for the candidate languages</span>
        <span style="color: #003399; font-weight: bold;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> tab = languageDetectionList.<span style="color: #006633;">split</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;,&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399; font-weight: bold;">ArrayList</span><span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>String<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> arr = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">ArrayList</span><span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>String<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Arrays</span>.<span style="color: #006633;">asList</span><span style="color: #009900;">&#40;</span>tab<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000;  font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span> i=<span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>arr.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>i++<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
           arr.<span style="color: #006633;">set</span><span style="color: #009900;">&#40;</span>i, arr.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Set the candidate languages</span>
        lrCnGram.<span style="color: #006633;">setCandidateLanguages</span><span style="color: #009900;">&#40;</span>arr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000;  font-weight: bold;">else</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Try to get a candidate languages list according to the charset</span>
        <span style="color: #003399; font-weight: bold;">ArrayList</span><span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>String<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> charSetCanditateLanguages<span style="color: #339933;">;</span>
        CharsetLanguages csu = <span style="color: #000000; font-weight: bold;">new</span> CharsetLanguages<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000;  font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>charSet == <span style="color: #006600; font-weight: bold;">null</span> || <span style="color: #0000ff;">&quot;&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>charSet<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            charSet =<span style="color: #0000ff;">&quot;utf-8&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #000000;  font-weight: bold;">else</span>
            charSet = csu.<span style="color: #006633;">getCharsetCanonicalName</span><span style="color: #009900;">&#40;</span>charSet<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000;  font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;utf-8&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>charSet<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #003399; font-weight: bold;">String</span> s = csu.<span style="color: #006633;">getUnicodeBlockDistribution</span> <span style="color: #009900;">&#40;</span>content<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            charSetCanditateLanguages = csu.<span style="color: #006633;">getUnicodeBlockLanguages</span><span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000;  font-weight: bold;">else</span>
        <span style="color: #009900;">&#123;</span>
            charSetCanditateLanguages = csu.<span style="color: #006633;">getCharsetLanguages</span><span style="color: #009900;">&#40;</span>charSet<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Only one possible language so nothing else to do</span>
        <span style="color: #000000;  font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>charSetCanditateLanguages<span style="color: #339933;">!</span>=<span style="color: #006600; font-weight: bold;">null</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> charSetCanditateLanguages.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>==<span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
            <span style="color: #000000; font-weight: bold;">return</span> charSetCanditateLanguages.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Set the candidate languages</span>
        lrCnGram.<span style="color: #006633;">setCandidateLanguages</span><span style="color: #009900;">&#40;</span>charSetCanditateLanguages<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Process the recognition</span>
    language = lrCnGram.<span style="color: #006633;">RecognizeLanguage</span><span style="color: #009900;">&#40;</span> content, <span style="color: #cc66cc;">0.5</span>, <span style="color: #006600; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> language<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Ajouter des langues à la liste de celles détectables par NGramJ</h3>
<p>Pour ce travail, je me suis inspiré de l&#8217;article suivant &laquo;&nbsp;<a href="http://blog.afterthedeadline.com/2009/12/04/generating-a-plain-text-corpus-from-wikipedia/" target="_blank">Generating a Plain Text Corpus from Wikipedia</a>&laquo;&nbsp;.</p>
<p>Pour ajouter une nouvelle langue, les étapes sont :</p>
<ul>
<li>Récupérer un corpus significatif de texte écrit dans cette langue</li>
<li>Nettoyer le texte</li>
<li>Créer le fichier modèle avec NGramJ</li>
</ul>
<h4>Obtenir un corpus</h4>
<p>Pour obtenir un corpus dans une langue donnée, il est possible de télécharger la totalité des articles de wikipedia dans cette langue. L&#8217;adresse dépend du code ISO de la langue :</p>
<p>http://download.wikimedia.org/&lt;code iso&gt;wiki/latest/&lt;code iso&gt;wiki-latest-pages-articles.xml.bz2</p>
<p>Par exemple, pour l&#8217;arabe, on récupère une archive et on la décompresse comme ceci :</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">curl -O http://download.wikimedia.org/arwiki/latest/arwiki-latest-pages-articles.xml.bz2
bunzip2 arwiki-latest-pages-articles.xml.bz2</pre></div></div>

<h4>Nettoyer le corpus</h4>
<p>Pour nettoyer le fichier xml, je me suis inspiré <a href="http://wiki.apertium.org/wiki/Talk:Calculating_coverage#wikicat2.sh" target="_blank">de ce script</a>.</p>
<p>Ma version est plus violent mais ne supprime pas ce qui n&#8217;est pas iso-8859-1.</p>
<p><em>wikicat2.sh :<br />
 </em></p>

<div class="wp_syntax"><div class="code"><pre class="sed" style="font-family:monospace;">#!/bin/sh
# http://wiki.apertium.org/wiki/Talk:Calculating_coverage#wikicat2.sh
# clean up wiki for running through apertium-destxt
# Use $ ./wikicat2.sh blah-pages-articles.xml.bz2
&nbsp;
# awk prints full lines, make sure each html element has one
#bzcat &quot;$@&quot; | sed 's/&amp;gt;/&amp;gt;n/g' | sed 's/&lt;!--n&lt;/g' |
cat &quot;$@&quot; | sed 's/--&gt;/&amp;gt;n/g' | sed 's/&lt;!--n&lt;/g' |
# want only stuff between &lt;text...--&gt; and
awk '
//,/&amp;lt;/text&amp;gt;/ { print $0 }
' |
&nbsp;
sed 's/[[([a-z]{2,3}):[^]]+]]//g' |
# Drop all transwiki links
&nbsp;
sed 's/[[[^]|]*|//g' | sed 's/]]//g' | sed 's/[[//g' |
# wiki markup, retain bar and fie from [[foo|bar]] [[fie]]
&nbsp;
sed 's/[http[^ ]*([^]]*)]/1/g' |
# wiki markup, retain `bar fie' from [http://foo bar fie]
&nbsp;
sed 's/&amp;amp;.*;/ /g' |
# remove entities greedily, so as to get rid of hidden html too
&nbsp;
# Keep only lines starting with a capital letter, removing tables with style info etc.
# grep '^[ t]*[A-ZÆØÅ]' # Your alphabet here
grep -vE '^([|{=}!]|[a-z]{2,3}:)' |
&nbsp;
# some other cleanup
grep -vE '^([a-z]{1,4}-[a-z]{1,4}:)' |
grep -vE '^([a-z]{1,4}-[a-z]{1,4}-[a-z]{1,4}:)' |
grep -vE '^s*[a-z]{0,2}s*$' |
grep -vE '^s*$' |
grep -vE &quot;([|]|'{3})&quot; |
&nbsp;
# keep a raisonnable corpus size
head -n 2000</pre></div></div>

<p>Et donc, pour générer un fichier nettoyé la commande est :</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">wikicat2.sh arwiki-latest-pages-articles.xml &amp;gt;ar.txt</pre></div></div>

<p>Ce script peut être à améliorer en fonction de résultat obtenu. Quoi qu&#8217;il en soit, il faut tout faire pour nettoyer au mieux le texte et même terminer le travail à la main si nécessaire.</p>
<h4>Créer le fichier model</h4>
<p>Le fichier modèle est généré à partir du texte nettoyé avec la commande suivante :</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">java -jar cngram.jar -create ar ar.txt &quot;UTF-8&quot;</pre></div></div>

<p>On peut enchainer automatiquement toutes ces taches en prenant soin de ne télécharger le corpus de wikipedia que si on ne l&#8217;a pas déjà. Voici comment préparer un environnement de travail et un script shell qui va enchainer toutes les opérations automatiquement pour une liste de langues.</p>
<p>1. dans un répertoire, on place cngram.jar et wikicat2.sh.</p>
<p>2. on y créer buildngp.sh</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">#!/bin/bash
&nbsp;
mkdir data &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
cd  data
mkdir ngp &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
&nbsp;
# for all these languages
for i in fr fa ar be mk sr uk; do
    echo $i
&nbsp;
    # download file from wikipedia only if necessary
    if [ -f ${i}wiki-latest-pages-articles.xml ];
    then
        echo &quot;${i}wiki-latest-pages-articles.xml exists in local&quot;
    else
        # download
        curl -O http://download.wikimedia.org/${i}wiki/latest/${i}wiki-latest-pages-articles.xml.bz2
        # unzip the file
        bunzip2 ${i}wiki-latest-pages-articles.xml.bz2
    fi
&nbsp;
    # cleanup the xml file to text file
    ../wikicat2.sh ${i}wiki-latest-pages-articles.xml &amp;gt; ${i}.txt
&nbsp;
    # create cngram ngp file
    java -jar ../cngram.jar -create ${i} ${i}.txt &quot;UTF-8&quot;
    mv ${i}.ngp ngp/${i}.ngp
done</pre></div></div>

<p>On lance le script ainsi en se positionnant dans le répertoire de travail :</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">./buildngp.sh</pre></div></div>

<p>Les données sont téléchargées dans le sous-répertoire data et les fichiers ngp créés dans data/ngp. Dans le script, la ligne suivante permet de définir la liste des langues pour lesquels ont va générer un fichier NPG.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">for i in fr fa ar be mk sr uk; do</pre></div></div>

<h3>Téléchargements<br class="spacer_" /></h3>
<p>Télécharger le projet Eclipse <a href="http://www.zoonix.fr/uploads/2010/03/charsetlanguagestar.gz">CharsetLanguages</a></p>
<p>Télécharger les scripts de génération de fichier NGP pour NgramJ <a href="http://www.zoonix.fr/uploads/2010/03/buildngptar.gz">BuildNGP</a></p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.eolya.fr/2010/03/26/detection-de-la-langue-d%e2%80%99un-texte-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tika 0.6 : compilation et dépendances</title>
		<link>http://www.eolya.fr/2010/03/11/tika-06-compilation-et-dependances/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tika-06-compilation-et-dependances</link>
		<comments>http://www.eolya.fr/2010/03/11/tika-06-compilation-et-dependances/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 20:48:55 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Lucene / Solr]]></category>
		<category><![CDATA[Technique]]></category>
		<category><![CDATA[Solr]]></category>
		<category><![CDATA[tika]]></category>

		<guid isPermaLink="false">http://www.zoonix.fr/?p=544</guid>
		<description><![CDATA[Tika est une librairie Java qui a pour but l&#8217;extraction du texte de toutes sortes de formats de fichiers : PDF, office,  html, &#8230; (la liste complète est disponible ici). Afin d&#8217;utiliser cette librairie dans vos projets java, il faut en récupérer les sources, les compiler et également récupérer les librairies dont dépend Tika. Voici [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zoonix.fr/uploads/2010/03/tika.png"><img class="alignleft size-full wp-image-550" title="tika" src="http://www.zoonix.fr/uploads/2010/03/tika.png" alt="tika" width="185" height="41" /></a>Tika est une librairie Java qui a pour but l&#8217;extraction du texte de toutes sortes de formats de fichiers : PDF, office,  html, &#8230; (la liste complète est disponible <a href="http://lucene.apache.org/tika/0.6/formats.html" target="_blank">ici</a>). Afin d&#8217;utiliser cette librairie dans vos projets java, il faut en récupérer les sources, les compiler et également récupérer les librairies dont dépend Tika. Voici la procédure à suivre ainsi qu&#8217;une astuce pour palier à un problème de compilation.<span id="more-544"></span></p>
<h3>Etape 1 : Récupérer les sources</h3>
<p>Les sources sont disponibles à partir de la page <a href="http://lucene.apache.org/tika/download.html" target="_blank">http://lucene.apache.org/tika/download.html</a></p>
<p>Décompresser l&#8217;archive dans un répertoire de travail /tmp/tika-0.6</p>
<h3>Etape 2 : Compilation.</h3>
<p>Le moyen le plus simple est d&#8217;utiliser <a href="http://maven.apache.org/" target="_blank">maven 2</a>.</p>
<p>On se place dans le répertoire de travail</p>
<pre style="padding-left: 30px;">cd /tmp/tika-0.6</pre>
<p>On positionne la variable d&#8217;environnement LC_ALL afin de ne pas avoir d&#8217;erreur durant la compilation (l&#8217;astuce) et on alloue par la même occasion suffisamment de mémoire de pour maven</p>
<pre style="padding-left: 30px;">export LC_ALL=en_US.UTF-8
export MAVEN_OPTS="-Xmx2048m"</pre>
<p>On lance la compilation</p>
<pre style="padding-left: 30px;">mvn install</pre>
<p>4 fichiers jar sont générés</p>
<pre style="padding-left: 30px;">find . -name *.jar -print</pre>
<pre style="padding-left: 30px;">./tika-app/target/tika-app-0.6.jar
./tika-bundle/target/tika-bundle-0.6.jar
./tika-core/target/tika-core-0.6.jar
./tika-parsers/target/tika-parsers-0.6.jar</pre>
<p>Pour utiliser Tika dans une application, seules les 2 jars suivants sont indispensables :</p>
<p>./tika-core/target/tika-core-0.6.jar<br />
 ./tika-parsers/target/tika-parsers-0.6.jar</p>
<p>Par contre, tika-parser-0.6.jar requière un certain nombre de librairies tierces. Les récupérer est la troisième étape.</p>
<h3>Etape 3 : Récupération des dépendances</h3>
<p>On se place dans le répertoire des sources de tika-parser</p>
<pre style="padding-left: 30px;">cd tika-parsers</pre>
<p>On demande à maven de récupérer les dépendances</p>
<pre style="padding-left: 30px;">mvn dependency:copy-dependencies</pre>
<p>Les dépendances sont disponibles dans le sous-répertoire target/dependency et il s&#8217;agit de:</p>
<pre style="padding-left: 30px;">./target/dependency/asm-3.1.jar
./target/dependency/commons-compress-1.0.jar
./target/dependency/commons-logging-1.1.1.jar
./target/dependency/dom4j-1.6.1.jar
./target/dependency/fontbox-0.8.0-incubator.jar
./target/dependency/geronimo-stax-api_1.0_spec-1.0.1.jar
./target/dependency/hamcrest-core-1.1.jar
./target/dependency/jempbox-0.8.0-incubator.jar
./target/dependency/junit-3.8.1.jar
./target/dependency/log4j-1.2.14.jar
./target/dependency/metadata-extractor-2.4.0-beta-1.jar
./target/dependency/mockito-core-1.7.jar
./target/dependency/objenesis-1.0.jar
./target/dependency/pdfbox-0.8.0-incubating.jar
./target/dependency/poi-3.6.jar
./target/dependency/poi-ooxml-3.6.jar
./target/dependency/poi-ooxml-schemas-3.6.jar
./target/dependency/poi-scratchpad-3.6.jar
./target/dependency/tagsoup-1.2.jar
./target/dependency/xml-apis-1.0.b2.jar
./target/dependency/xmlbeans-2.3.0.jar</pre>
<p><br class="spacer_" /></p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.eolya.fr/2010/03/11/tika-06-compilation-et-dependances/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Déconnexions intempestives avec SSH</title>
		<link>http://www.eolya.fr/2010/01/11/deconnexions-intempestives-avec-ssh/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=deconnexions-intempestives-avec-ssh</link>
		<comments>http://www.eolya.fr/2010/01/11/deconnexions-intempestives-avec-ssh/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 12:16:37 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Technique]]></category>

		<guid isPermaLink="false">http://www.zoonix.fr/?p=454</guid>
		<description><![CDATA[Avec ma connexion Numéricable (mais pas en ADSL avec Free), j&#8217;ai rencontré des problèmes de déconnexions SSH intempestives (aussi bien avec Putty qu&#8217;avec WinSCP). La solutions passe par une paramétrage du coté client pour envoyer des packets vides qui serviront à maintenir la connexion en vie. Avec Putty : Onglet Connections &#62; Seconds between keepalives [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zoonix.fr/uploads/2010/01/ssh1.jpg"><img class="alignleft size-full wp-image-489" title="ssh1" src="http://www.zoonix.fr/uploads/2010/01/ssh1.jpg" alt="ssh1" width="100" height="51" /></a>Avec ma connexion Numéricable (mais pas en ADSL avec Free), j&#8217;ai rencontré des problèmes de déconnexions SSH intempestives (aussi bien avec Putty qu&#8217;avec WinSCP).</p>
<p>La solutions passe par une paramétrage du coté client pour envoyer des packets vides qui serviront à maintenir la connexion en vie.</p>
<p>Avec Putty : Onglet Connections &gt; Seconds between keepalives : &laquo;&nbsp;60&#8243;</p>
<p>Sous Linux :  Dans &laquo;&nbsp;~/.ssh/config&nbsp;&raquo; &gt; &laquo;&nbsp;ServerAliveInterval 60&#8243;</p>
<p>Dans les cas ou cela est possible, cette configuration peut être réalisée coté serveur : dans &laquo;&nbsp;/etc/ssh/sshd_config&nbsp;&raquo; &gt; &laquo;&nbsp;ClientAliveInterval 60&#8243;</p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.eolya.fr/2010/01/11/deconnexions-intempestives-avec-ssh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mac OS X et outils de développement</title>
		<link>http://www.eolya.fr/2009/12/20/mac-os-x-et-outils-de-developpement/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mac-os-x-et-outils-de-developpement</link>
		<comments>http://www.eolya.fr/2009/12/20/mac-os-x-et-outils-de-developpement/#comments</comments>
		<pubDate>Sat, 19 Dec 2009 23:27:08 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Mac OS]]></category>
		<category><![CDATA[Productivité]]></category>
		<category><![CDATA[Technique]]></category>

		<guid isPermaLink="false">http://www.zoonix.fr/?p=401</guid>
		<description><![CDATA[Le but est de pouvoir d&#233;velopper sous Mac OX (Snow Leopard) des applications AMP (Apache / MySQL / PHP) et des applications Java (dont des servlets dans Tomcat). Dans cet article sont abord&#233;es les installations de Apache, PHP, MySQL, Java, Tomcat et Eclipse. &#160; &#160; Xcode C&#39;est la premi&#232;re &#233;tape incontournable pour disposer d&#39;un environnement [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zoonix.fr/uploads/2009/12/icon_xcode_20090824.png"><img alt="icon_xcode_20090824" class="alignleft size-full wp-image-437" height="106" src="http://www.zoonix.fr/uploads/2009/12/icon_xcode_20090824.png" title="icon_xcode_20090824" width="91" /></a></p>
<p>Le but est de pouvoir d&eacute;velopper sous Mac OX (Snow Leopard) des applications AMP (Apache / MySQL / PHP) et des applications Java (dont des servlets dans Tomcat). Dans cet article sont abord&eacute;es les installations de Apache, PHP, MySQL, Java, Tomcat et Eclipse.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Xcode</h3>
<p>C&#39;est la premi&egrave;re &eacute;tape incontournable pour disposer d&#39;un environnement de d&eacute;veloppement sous Mac OS. Xcode est disponible sur le DVD de Snow Leopard, mais la derni&egrave;re version &agrave; jour est disponible gratuitement sur le site de Apple (http://developer.apple.com/products/membership.html). Xcode inclut les outils minimums pour cr&eacute;er et debugger des applications pour Mac (ou iPhone).</p>
<h3><span id="more-401"></span>Java</h3>
<p>Pour Java, il n&#39;y a rien &agrave; faire puisque le JDK 1.6 est inclus dans Snow Leopard.</p>
<h3>MySQL</h3>
<p>Pour install&eacute; MySQL, j&#39;ai suivi la proc&eacute;dure d&eacute;crite dans cette page &quot;<a href="http://hivelogic.com/articles/installing-mysql-on-mac-os-x" target="_blank">Installing MySQL on Mac OS X</a>&quot;. Je l&#39;ai juste appliqu&eacute;e &agrave; une version 5.0.88.</p>
<p>A noter cette article &eacute;galement qui d&eacute;crit en plus la cr&eacute;ation d&#39;un user mysql &quot;<a href="http://www.malisphoto.com/tips/mysql-on-os-x.html" target="_blank">Compiling and Installing MySQL 5 on Mac OS X Leopard</a>&quot;</p>
<h3>Apache</h3>
<p>Comme pour Java, il n&#39;y a rien &agrave; faire puisque Apache 2.2 est install&eacute; avec Snow Leopard (Partage web).</p>
<h3>PHP</h3>
<p>Apache est install&eacute; avec Snow Leopard donc en toute logique PHP l&#39;est &eacute;galement (mais n&#39;est pas actif dans Apache par d&eacute;faut). Le probl&egrave;me (pas forc&eacute;ment pour tout le monde) est qu&#39;il s&#39;agit de la version 5.3 et que j&#39;ai besoin de la version 5.2.x. Il faut donc downgrader PHP.</p>
<h4>Activation de Php 5.3 dans Apache</h4>
<p>Il suffit de d&eacute;commenter la ligne suivante dans /etc/apache2/httpd.conf.</p>
<pre>#LoadModule php5_module        libexec/apache2/libphp5.so</pre>
<h4>Downgrader Php en version 5.2.x</h4>
<p>Pour cela, soit on utilise une distribution 5.2.x pour Mac OS toute pr&ecirc;te, soit on compile soit m&ecirc;me Php. Pour utiliser une distribution toutes pr&ecirc;te de Php 5.2.9 pour Mac OS, on se rend sur le site de <a href="http://www.entropy.ch/home/welcome.php" target="_blank">Marc Liyanage</a>. Outre <a href="http://www.entropy.ch/software/macosx/php/" target="_blank">la page sur les distributions de Php pour Mac OS</a>, ce site fournit des informations sur Mac OS en g&eacute;n&eacute;ral, MySQL, Java et Perl.</p>
<p class="title">J&#39;ai choisi de compiler moi m&ecirc;me Php afin de disposer d&#39;une version &agrave; jour (5.2.11). Pour cela, je me suis principalement bas&eacute; sur cet article &quot;<a href="http://pixelchimp.net/blog/pixel-chimp/reverting-php-53-5210-snow-leopard" target="_blank">Reverting PHP 5.3 to 5.2.10 on Snow Leopard</a>&quot;. Le seul changement que j&#39;ai apport&eacute; &agrave; la proc&eacute;dure d&eacute;crite concerne la configuration de la compilation de Php. J&#39;ai utilis&eacute; cette ligne de commande afin d&#39;activer entre autres l&#39;option sockets.</p>
<pre class="title">./configure
&nbsp;&nbsp;&nbsp; --prefix=/usr/local/php5
&nbsp;&nbsp;&nbsp; --with-apxs2
&nbsp;&nbsp;&nbsp; --enable-pdo
&nbsp;&nbsp;&nbsp; --enable-ftp
&nbsp;&nbsp;&nbsp; --enable-mbstring
&nbsp;&nbsp;&nbsp; --enable-mbregex
    --enable-soap
&nbsp;&nbsp;&nbsp; --enable-sockets
&nbsp;&nbsp;&nbsp; --enable-gd-native-ttf
&nbsp;&nbsp;&nbsp; --enable-cli
&nbsp;&nbsp;&nbsp; --with-freetype-dir=/usr/local/lib
&nbsp;&nbsp;&nbsp; --with-t1lib=/usr/local/lib
&nbsp;&nbsp;&nbsp; --with-gd
&nbsp;&nbsp;&nbsp; --with-zlib
&nbsp;&nbsp;&nbsp; --with-jpeg-dir=/usr/local/lib
&nbsp;&nbsp;&nbsp; --with-png-dir=/usr/local/lib
&nbsp;&nbsp;&nbsp; --with-curl
&nbsp;&nbsp;&nbsp; --with-mcrypt
&nbsp;&nbsp;&nbsp; --with-pdo_mysql=/usr/local/mysql
&nbsp;&nbsp;&nbsp; --with-mysql=/usr/local/mysql/
&nbsp;&nbsp;&nbsp; --with-mysqli=/usr/local/mysql/bin/mysql_config
&nbsp;&nbsp;&nbsp; --without-iconv</pre>
<p class="title">Je regrette de n&#39;avoir pas r&eacute;ussi &agrave; installer et activer la librairie iconv &agrave; cause d&#39;une erreur de compilation. Normalement, la solution est dans <a href="http://bugs.php.net/bug.php?id=49267" target="_blank">cette page</a>, mais pour moi, cela n&#39;a pas (encore) fonctionn&eacute;.</p>
<p>Durant mes recherches, j&#39;ai &eacute;galement trouv&eacute; ces articles int&eacute;ressants :</p>
<ul>
<li><a href="http://www.malisphoto.com/tips/php-on-os-x.html#Anchor-Backup" target="_blank">Enabling, Compiling and Installing PHP 5 on Mac OS X Leopard</a></li>
<li><a href="http://adylitica.com/2009/11/24/installing-amp-apache-mysql-php-on-mac-os-x-10-6-snow-leopard/" target="_blank">Installing AMP (Apache, MySQL, PHP) on Mac OS X 10.6 Snow Leopard</a></li>
</ul>
<p>Note : pour l&#39;installation de soap.so, voir&nbsp;<a href="http://www.bdoran.co.uk/2010/08/03/installing-php-soap-on-osx-leopard-10-6-4/" target="_blank">http://www.bdoran.co.uk/2010/08/03/installing-php-soap-on-osx-leopard-10-6-4/</a></p>
<h3>Tomcat</h3>
<p>On trouve beaucoup d&#39;articles d&eacute;crivant l&#39;installation de Tomcat sous Mac OS. Pour des raisons de compatibilit&eacute;s avec les serveurs Tomcat que je g&egrave;re et pour lesquels je d&eacute;veloppe, je souhaite installer une version 5.5. Je me suis bas&eacute; sur cet article : <a href="http://philatwarrimoo.blogspot.com/2009/08/apache-tomcat-55-installation-on-mac-os.html" target="_blank">Apache Tomcat 5.5 Installation on Mac OS-X Leopard 10.5.x</a>.</p>
<p>De mon cot&eacute;, j&#39;ai install&eacute; Tomcat dans /opt/apache-tomcat-5.5.28. J&#39;ai &eacute;galement changer le port d&#39;&eacute;coute de Tomcat de 8080 &agrave; 8180 comme sous Debian. La version de Java install&eacute;e avec Snow Leopard est la 1.6 donc dans startup.sh, les variables JAVA_HOME et CATALINA_HOME sont les suivantes :</p>
<pre>export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/
export CATALINA_HOME=/opt/apache-tomcat-5.5.28</pre>
<p>Durant mes recherches, j&#39;ai &eacute;galement trouv&eacute; ces articles int&eacute;ressants :</p>
<ul>
<li><a href="http://www.malisphoto.com/tips/tomcatonosx.html" target="_blank">Installing Apache Tomcat 6 on Mac OS X Leopard</a></li>
<li><a href="http://wiki.apache.org/tomcat/TomcatOnMacOS" target="_blank">Running Tomcat on Macintosh OS X</a></li>
</ul>
<p>Dans ce dernier article est expliqu&eacute; comment faire afin que Tomcat d&eacute;marre automatiquement comme un demon. Il y plusieurs solutions et j&#39;ai choisi la suivante :</p>
<p>1. Positionner les variables d&#39;environnement JAVA_HOME et CATALINA_HOME au d&eacute;but du script /opt/apache-tomcat-5.5.28/bin/catalina.sh</p>
<p>2. Cr&eacute;er un fichier /Library/LaunchDaemons/org.apache.tomcat.plist qui contient ceci.</p>
<pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE plist PUBLIC &quot;-//Apple Computer//DTD PLIST 1.0//EN&quot;
&quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
&lt;dict&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;key&gt;Disabled&lt;/key&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;false/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;key&gt;Label&lt;/key&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;string&gt;org.apache.tomcat&lt;/string&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;key&gt;ProgramArguments&lt;/key&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;array&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;string&gt;/opt/apache-tomcat-5.5.28/bin/catalina.sh&lt;/string&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;string&gt;run&lt;/string&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/array&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;key&gt;RunAtLoad&lt;/key&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;true/&gt;
&lt;/dict&gt;
&lt;/plist&gt;
</pre>
<p>et lui affecter le bon propri&eacute;taire :</p>
<pre>sudo chown root:wheel /Library/LaunchDaemons/org.apache.tomcat.plist</pre>
<p>Le d&eacute;marrage et l&#39;arr&ecirc;t manuel de Tomcat se font ainsi :</p>
<pre>sudo launchctl load /Library/LaunchDaemons/org.apache.tomcat.plist</pre>
<pre>sudo launchctl unload /Library/LaunchDaemons/org.apache.tomcat.plist
</pre>
<h3>Eclipse pour Java et Php</h3>
<p>Pour l&#39;installation de Eclipse, ma source d&#39;informations est cet article <a href="http://blog.zvikico.com/2009/10/installing-eclipse-galileo-on-mac-os-x.html" target="_blank">Installing Eclipse Galileo on Mac OS X</a>, mais on peut &eacute;galement regarder du cot&eacute; de la distribution <a href="http://www.poweredbypulse.com/index.php" target="_blank">Pulse</a>.</p>
<h4>Java</h4>
<p>La proc&eacute;dure est simple :</p>
<p>1. Sur <a href="http://eclipse.org/downloads/" target="_blank">la page de t&eacute;l&eacute;chargement de Eclipse</a>,&nbsp; r&eacute;cup&eacute;rer la version Cocoa 32 bits de &quot;Eclipse IDE for Java EE Developers&quot; ou de &quot;Eclipse IDE for Java Developers&quot; et d&eacute;compresser l&#39;archive r&eacute;cup&eacute;r&eacute;e. Un r&eacute;pertoire &quot;eclipse&quot; est cr&eacute;&eacute;.</p>
<p>2. Cr&eacute;er un r&eacute;pertoire /Applications/Dev et y copier le r&eacute;pertoire &quot;eclipse&quot; issue de la d&eacute;compression de l&#39;archive.</p>
<h4>Php</h4>
<p>Pour la version Php de Eclipse (Eclipse for PHP Developers), la proc&eacute;dure est exactement la m&ecirc;me. Avant de copier dans /Applications/dev le r&eacute;pertoire cr&eacute;&eacute; par la d&eacute;compression de l&#39;archive, je le renomme &quot;eclipse php&quot;.</p>
<h4>Xdebug pour Php</h4>
<p>Pour Eclipse Php, il est n&eacute;cessaire d&#39;installer le composant de debuggage Xdebug.</p>
<p>Sur la page <a href="http://aspn.activestate.com/ASPN/Downloads/Komodo/RemoteDebugging/" target="_blank">http://aspn.activestate.com/ASPN/Downloads/Komodo/RemoteDebugging/</a>, on t&eacute;l&eacute;charge dans la section &quot;Komodo 5.2 Remote Debugging Packages&quot; le module &quot;PHP Remote Debugging&quot; pour Mac OS X. Une fois d&eacute;compress&eacute;, l&#39;archive contient la librairy xdebug.so pour diff&eacute;rentes versions de Php.</p>
<p>Dans un terminal ex&eacute;cuter la commande qui suit (sur une seule ligne) en rempla&ccedil;ant les &quot;x&quot; par les valeurs correspondants &agrave; la version que vous aurez t&eacute;l&eacute;charg&eacute;e :</p>
<pre>sudo cp ~/Downloads/Komodo-PHPRemoteDebugging-5.2.x-xxxxx-macosx/5.2/xdebug.so
/usr/local/php5/include/php/ext/</pre>
<p>Dans php.ini (/usr/local/php5/lib/php.ini), ajoutez les lignes suivantes &agrave; la fin du fichier&nbsp;:</p>
<pre>zend_extension=/usr/local/php5/include/php/ext/xdebug.so

[Xdebug]
xdebug.remote_enable=1
xdebug.remote_host=localhost
xdebug.remote_port=9000
xdebug.remote_autostart=1
xebug.remote_handler=dbgp
</pre>
<p>Red&eacute;marrez Apache (Pr&eacute;f&eacute;rences Syst&egrave;me -&gt; partage -&gt; partage web).</p>
<p>&nbsp;</p>
<h3>Sites utiles</h3>
<ul>
<li><a href="http://www.entropy.ch/home/welcome.php" target="_blank">http://www.entropy.ch/home/welcome.php</a></li>
<li><a href="http://blog.zvikico.com/" target="_blank">http://blog.zvikico.com/</a></li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.eolya.fr/2009/12/20/mac-os-x-et-outils-de-developpement/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Introduction à Solr &#8211; Installation et configuration (2)</title>
		<link>http://www.eolya.fr/2009/05/10/introduction-a-solr-installation-et-configuration-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introduction-a-solr-installation-et-configuration-2</link>
		<comments>http://www.eolya.fr/2009/05/10/introduction-a-solr-installation-et-configuration-2/#comments</comments>
		<pubDate>Sun, 10 May 2009 22:57:47 +0000</pubDate>
		<dc:creator>dominique</dc:creator>
				<category><![CDATA[Lucene / Solr]]></category>
		<category><![CDATA[Moteur de recherche]]></category>
		<category><![CDATA[Productivité]]></category>
		<category><![CDATA[Technique]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[Solr]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://www.zoonix.fr/?p=271</guid>
		<description><![CDATA[Dans les précédents articles consacrés à Solr, j&#8217;en décris les principes (Présentation de Lucene Solr) et  comment installer et configurer de façon très basique Solr afin de pouvoir indexer et rechercher dans le jeu de données de test fourni dans la distribution (Introduction à Solr &#8211; Installation et configuration (1)). Dans ce nouvel article, je [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zoonix.fr/uploads/2008/09/solr.png"><img class="alignleft size-medium wp-image-83" title="solr" src="http://www.zoonix.fr/uploads/2008/09/solr.png" alt="" width="86" height="44" /></a>Dans les précédents articles consacrés à <strong>Solr</strong>, j&#8217;en décris les principes (<a href="http://www.zoonix.fr/2008/09/18/presentation-de-lucene-solr/">Présentation de Lucene Solr</a>) et  comment installer et configurer de façon très basique <strong>Solr </strong>afin de pouvoir indexer et rechercher dans le jeu de données de test fourni dans la distribution (<a href="http://www.zoonix.fr/2008/12/08/introduction-a-solr-installation-et-configuration-1/">Introduction à Solr &#8211; Installation et configuration (1)</a>).</p>
<p>Dans ce nouvel article, je vais expliquer plus en détail les points suivants :</p>
<ul>
<li>Le contenu de la distribution</li>
<li>Les fichiers de configuration</li>
<li>Comment gérer plusieurs indexes ?</li>
<li>Comment gérer plusieurs applications ?</li>
</ul>
<p><span id="more-271"></span></p>
<h3>Le contenu de la distribution</h3>
<p>Une fois récupérée et décompressée dans un répertoire, la distribution de Solr contient différents répertoires.</p>
<table border="0">
<tbody>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Client</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">Des API clientes pour Java (solrj) et Ruby (solr-ruby). Il existe en fait des solutions d&#8217;intégration avec d&#8217;autres langages (Perl, PHP, Python, C#, &#8230;). Une liste est disponible <a href="http://wiki.apache.org/solr/IntegratingSolr" target="_blank">ici </a>sur le wiki de Solr.</td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Contrib</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">
<p>Des outils qui contribuent à étendre les fonctionnalités de Solr. Dans la distribution 1.3.0, il s&#8217;agit uniquement de l&#8217;outil dataimporthandler pour l&#8217;importation et l&#8217;indexation de données issues d&#8217;une base de données.</p>
<p>Dans les versions futures, il pourrait s&#8217;agir également d&#8217;un outil d&#8217;extraction du contenu de documents Office ou PDF (basé sur Tika), d&#8217;une intégration avec <a href="http://code.google.com/p/jsdoc-toolkit/" target="_blank">Jsdoc Toolkit</a> et d&#8217;une intégration avec le <a href="http://velocity.apache.org/engine/index.html" target="_blank">framework Velocity</a>.</p>
</td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Dist</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">Les binaires issus de la compilation des sources de <strong>Solr </strong>et les librairies dont dépend <strong>Solr</strong>.</td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Docs</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">La documentation de <strong>Solr</strong></td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Example</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">Des exemples de mise en oeuvre et le nécessaire pour exécuter Solr avec Jetty. Les principaux sous-répertoires sont :</td>
</tr>
<tr>
<td></td>
<td colspan="2"><strong>Multicore</strong></td>
</tr>
<tr>
<td></td>
<td style="width: 20px;"></td>
<td>Exemple de paramétrage en mode multi-core afin de gérer des applications et des index multiples dans une même webapp du serveur J2EE.</td>
</tr>
<tr>
<td></td>
<td colspan="2"><strong>Solr</strong></td>
</tr>
<tr>
<td></td>
<td style="width: 20px;"></td>
<td>Exemple de répertoire &laquo;&nbsp;Home&nbsp;&raquo; de Solr et fichiers de configuration par défaut.</td>
</tr>
<tr>
<td></td>
<td colspan="2"><strong>Webapps</strong></td>
</tr>
<tr>
<td></td>
<td style="width: 20px;"></td>
<td>Le fichier war à déployer dans la serveur J2EE et utiliser par le lanceur jetty fourni en exemple.</td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Lib</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">Les librairies java dont dépend <strong>Solr</strong></td>
</tr>
<tr>
<td style="background-color: #dcdcdc;" colspan="3"><strong>Src</strong></td>
</tr>
<tr>
<td style="width: 20px;"></td>
<td colspan="2">Les sources de <strong>Solr</strong></td>
</tr>
</tbody>
</table>
<p>Mettre en place un environnement d&#8217;exécution de Solr à partir des éléments de la distribution est très simple. Il faut :</p>
<ol>
<li>créer un  environnement d&#8217;exécution en copiant le répertoire &laquo;&nbsp;/example/solr&nbsp;&raquo;, sous par exemple &laquo;&nbsp;/opt/solr&nbsp;&raquo; sous Linux ou &laquo;&nbsp;c:/solr&nbsp;&raquo; sous windows </li>
<li>copier le fichier solr.war contenu dans le répertoire webapps des exemples vers le répertoire approprié du serveur d&#8217;application (répertoire webapps par exemple pour Tomcat)</li>
<li>configurer le serveur d&#8217;application pour qu&#8217;il soit lancé avec la variable d&#8217;environnement solr.home.home pointant vers le répertoire  d&#8217;exécution (par exemple : -Dsolr.solr.home=/opt/solr) et le redémarrer</li>
</ol>
<p>Dans le répertoire pointé par la variable d&#8217;environnement &laquo;&nbsp;solr.solr.home&nbsp;&raquo;, on retrouve donc les répertoires &laquo;&nbsp;bin&nbsp;&raquo; (scripts utilitaires pour un environnement Linux), &laquo;&nbsp;conf&nbsp;&raquo; (fichiers de configuration) et &laquo;&nbsp;data&nbsp;&raquo; (y sera entre autres localisés l&#8217;index Lucene des données indexées).</p>
<h3>Les fichiers de configuration</h3>
<p>Les fichiers de configuration sont localisés dans le répertoire &laquo;&nbsp;/conf&nbsp;&raquo;. Il s&#8217;agit principalement de solrconfig.xml et schema.xml.</p>
<h4>solrconfig.xml</h4>
<p>Il s&#8217;agit du fichier qui contient l&#8217;essentiel des paramètres liés au fonctionnement de Solr et plus particulièrement des paramètres de l&#8217;API Lucene qu&#8217;utilise Solr (longueur maximale d&#8217;une champs, taille des buffer mémoire, fréquence de commit, &#8230;) . Ce fichier est très bien auto-documenté et fait l&#8217;objet <a href="http://wiki.apache.org/solr/SolrConfigXml" target="_blank">d&#8217;un document a part entière dans le wiki Solr</a>.</p>
<h4>schema.xml</h4>
<p>Il s&#8217;agit du fichier qui décrit comment seront indexées les données dans Solr. Il définit les types de données, les champs, les manipulations sur les données lors de l&#8217;indexation, les champs obligatoires, le champ de requête par défaut, &#8230;</p>
<p>Ce fichier est très bien auto-documenté et fait l&#8217;objet <a href="http://wiki.apache.org/solr/SchemaXml" target="_blank">d&#8217;un document a part entiere dans le wiki Solr</a>.</p>
<h5>Exemple de déclaration d&#8217;un type</h5>
<p>&lt;fieldType name=”string” class=”solr.StrField” sortMissingLast=”true” omitNorms=”true”/&gt;</p>
<p>Ce type a pour nom &laquo;&nbsp;string&nbsp;&raquo;, il sera pris en charge lors de l&#8217;indexation par la classe &laquo;&nbsp;solr.StrField&nbsp;&raquo;, lors d&#8217;un tri du résultat sur ce champ, les documents ne le possédant pas seront positionnés en dernier (sortMissingLast=&nbsp;&raquo;true&nbsp;&raquo;) et lors de l&#8217;indexation les informations de normalisation basées sur la taille du champ seront calculées et stockées (omitNorms=&nbsp;&raquo;true&nbsp;&raquo;).</p>
<h5>Exemple de déclaration d&#8217;un champ</h5>
<p>Les données indexées dans <strong>Solr </strong>par le service d&#8217;indexation sont contenues dans un <a href="http://fr.wikipedia.org/wiki/Datagramme" target="_blank">datagramme </a>de type XML. Lorsque Solr traite ce datagramme, il rapproche le nom de chaque élément XML avec le nom d&#8217;un champ. Il manipule alors la donnée associé à cet élément comme cela est défini par la définition du champ.</p>
<p>&lt;field name=”word” type=”string” indexed=”true” stored=”true”/&gt;</p>
<p>Ce champ est du type &laquo;&nbsp;string&nbsp;&raquo; (donc il hérite des propriétés de ce type). Il est indexé (donc les recherches peuvent porter sur son contenu) et les données de ce champs sont stokées (donc elles peuvent être récupérées au moment de l&#8217;affichage d&#8217;une liste de résultats par exemple).</p>
<p>D&#8217;autres paramètres importants peuvent également être définis lors de la déclaration d&#8217;un champ. Il s&#8217;agit de la méthode d&#8217;analyse lors de &#8216;indexation ou de la recherche. La méthode d&#8217;analyse permet de définir comment seront traitées les données du champ, à savoir son mode de découpage en mots (tokenizer) et les filtres qui lui seront appliqués (filter). Les filtres permettent par exemple de supprimer les mots vides, de mettre tous les mots en minuscule, de convertir les mots accentués en leurs équivalents sans accent, &#8230;</p>
<h5>Exemple de déclaration d&#8217;un champ dynamique</h5>
<p>Une déclaration de champ dynamique permet d&#8217;associer un traitement à des éléments du datagramme XML même si ces derniers ne sont pas spécifiquement déclarés comme champs.</p>
<p>&lt;dynamicField name=”*_s”  type=”string”  indexed=”true”  stored=”true”/&gt;</p>
<p>Tout élément du datagramme XML dont le nom se termine par &laquo;&nbsp;_s&nbsp;&raquo;, est considéré comme un élément de nom &laquo;&nbsp;string&nbsp;&raquo;.</p>
<h3>Comment gérer plusieurs indexes ?<br />
</h3>
<p>Par défaut, une instance Solr ne peut manipuler qu&#8217;un index. Comment faire si mon application doit permettre l&#8217;indexation de plusieurs types de données comme par exemple un annuaire de personnes et les messages d&#8217;un forum de discussion ?</p>
<p>Jusqu&#8217;à la version de 1.2 de Solr, il existait 2 solutions : associer un type à chaque document dans l&#8217;index (personne, message, &#8230;) ou utiliser plusieurs webapps dans le serveur J2EE et les faire pointer vers des environnements différents (-D=solr.solr.home=&#8230;). L&#8217;association d&#8217;un type à chaque document permet lors de la recherche de filtrer la liste de résultats en se limitant aux documents d&#8217;un ou plusieurs types. Utiliser plusieurs webapps permet d&#8217;utiliser un index distinct pour chaque type de documents.</p>
<p>Avec la version 1.3 de Solr est apparue la notion de &laquo;&nbsp;SolrCore&nbsp;&raquo; multiples. Un &laquo;&nbsp;SolrCore&nbsp;&raquo; est un environnement complet Solr (configuration et index) qui est exécuté par une webapps du serveur j2EE. Il est donc possible au moyen d&#8217;une seule webapps Solr de gérer plusieurs &laquo;&nbsp;SolrCore&nbsp;&raquo;. les SolrCore sont déclarés dans un fichier XML &laquo;&nbsp;solr.xml&nbsp;&raquo; localisé dans le répertoire solr.solr.home associé à la webapp. <br class="spacer_" /></p>
<h4>Exemple d&#8217;un environnement mono-core</h4>
<p>solr.solr.home=/opt/solr</p>
<p>Les répertoires d&#8217;installation sont organisés comme ceci :</p>
<pre>/opt
    /solr
        /bin
        /conf
        /data
        /webapps
            solr.war
</pre>
<p>Pour un paramétrage de Tomcat au moyen de JNDI, on place dans le répertoire conf/Calalina/localhost de Tomcat, le fichier solr.xml suivant :</p>
<pre>&lt;Context docBase="/opt/solr/webapps/solr.war" debug="0" crossContext="true" &gt;
    &lt;Environment
        name="solr/home"
        type="java.lang.String"
        value="/opt/solr/" override="true" /&gt;
&lt;/Context&gt;
</pre>
<p>Les urls d&#8217;accès à l&#8217;administration et aux web service Solr sont :</p>
<table border="1">
<tbody>
<tr>
<td>Administration</td>
<td>=&gt;</td>
<td>http://&lt;server&gt;:&lt;port&gt;/solr/admin/</td>
</tr>
<tr>
<td>Indexation / suppression</td>
<td>=&gt;</td>
<td>http://&lt;server&gt;:&lt;port&gt;/solr/update</td>
</tr>
<tr>
<td>Recherche</td>
<td>=&gt;</td>
<td>http://&lt;server&gt;:&lt;port&gt;/solr/select</td>
</tr>
</tbody>
</table>
<h4>Exemple d&#8217;un environnement multi-core</h4>
<p>solr.solr.home=/opt/solr</p>
<p>Les répertoires d&#8217;installation sont organisés comme ceci :</p>
<pre>/opt
    /solr
        solr.xml
        /core0
            /bin
            /conf
            /data
        /core1
            /bin
            /conf
            /data
        /webapps
            solr.war
</pre>
<p>Pour un paramétrage de Tomcat au moyen de JNDI, on place dans le répertoire conf/Calalina/localhost de Tomcat, le fichier solr.xml suivant :</p>
<pre>&lt;Context docBase="/opt/solr/webapps/solr.war" debug="0" crossContext="true" &gt;
    &lt;Environment
        name="solr/home"
        type="java.lang.String"
        value="/opt/solr/" override="true" /&gt;
&lt;/Context&gt;</pre>
<p>Dans le répertoire pointé par solr.solr.home, on place de féchier solr.xml suivant :</p>
<pre>&lt;solr persistent="true" sharedLib="lib"&gt;
    &lt;cores adminPath="/admin/cores"&gt;
        &lt;core name="core0" instanceDir="core0" /&gt;
        &lt;core name="core1" instanceDir="core1" /&gt;
    &lt;/cores&gt;
&lt;/solr&gt;
</pre>
<p>Les urls d&#8217;accès à l&#8217;administration et aux web service Solr des cores 0 et 1 sont :</p>
<table border="1">
<tbody>
<tr>
<td valign="top">Administration</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/solr/core0/admin/ </p>
<p>http://&lt;server&gt;:&lt;port&gt;/solr/core1/admin/</td>
</tr>
<tr>
<td valign="top">Indexation / suppression</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/solr/core0/update </p>
<p>http://&lt;server&gt;:&lt;port&gt;/solr/core1/update</td>
</tr>
<tr>
<td valign="top">Recherche</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/solr/core0/select  </p>
<p>http://&lt;server&gt;:&lt;port&gt;/solr/core1/select</td>
</tr>
</tbody>
</table>
<h3>Comment gérer plusieurs applications ?</h3>
<p>Imaginons que vous souhaitez indexer des données issues de différentes applications, pour l&#8217;exemple, un outil de gestion de contenu (ECM) et un forum de discussion. Chacune de ces applications nécessitant l&#8217;indexation de 2 types de données totalement différentes, pour l&#8217;exemple, des utilisateurs et des documents (ECM) ou des messages (forum).</p>
<p>Dans ce cas, je propose d&#8217;utiliser une webapp par application et un core par type de données.</p>
<p>On a donc un environnement comme celui-ci :</p>
<p>solr.solr.home=/opt/solr</p>
<p>Les répertoires d&#8217;installation sont organisés comme ceci :</p>
<pre>/opt
    /solr
        /ecm
            solr.xml
            /utilisateurs
                /bin
                /conf
                /data
            /documents
                /bin
                /conf
                /data
        /forum
            solr.xml
            /utilisateurs
                /bin
                /conf
                /data
            /messages
                /bin
                /conf
                /data
        /webapps
            solr.war
</pre>
<p>Pour un paramétrage de Tomcat au moyen de JNDI, on place dans le répertoire conf/Calalina/localhost de Tomcat, le fichier ecm.xml suivant :</p>
<pre>&lt;Context docBase="/opt/solr/webapps/solr.war" debug="0" crossContext="true" &gt;
    &lt;Environment
        name="solr/home"
        type="java.lang.String"
        value="/opt/solr/ecm" override="true" /&gt;
&lt;/Context&gt;</pre>
<p>et le fichier forum.xml suivant :</p>
<pre>&lt;Context docBase="/opt/solr/webapps/solr.war" debug="0" crossContext="true" &gt;
    &lt;Environment
        name="solr/home"
        type="java.lang.String"
        value="/opt/solr/forum" override="true" /&gt;
&lt;/Context&gt;</pre>
<p>Dans le répertoire &laquo;&nbsp;/opt/solr/ecm&nbsp;&raquo;, on place de féchier solr.xml suivant :</p>
<pre>&lt;solr persistent="true" sharedLib="lib"&gt;
    &lt;cores adminPath="/admin/cores"&gt;
        &lt;core name="utilisateurs" instanceDir="utilisateurs" /&gt;
        &lt;core name="documents" instanceDir="documents" /&gt;
    &lt;/cores&gt;
&lt;/solr&gt;
</pre>
<p>Dans le répertoire &laquo;&nbsp;/opt/solr/forum&nbsp;&raquo;, on place de féchier solr.xml suivant :</p>
<pre>&lt;solr persistent="true" sharedLib="lib"&gt;
    &lt;cores adminPath="/admin/cores"&gt;
        &lt;core name="utilisateurs" instanceDir="utilisateurs" /&gt;
        &lt;core name="messages" instanceDir="messages" /&gt;
    &lt;/cores&gt;
&lt;/solr&gt;
</pre>
<p>Les urls d&#8217;accès à l&#8217;administration et aux web service Solr de l&#8217;application ECM sont :</p>
<table border="1">
<tbody>
<tr>
<td valign="top">Administration</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/ecm/utilisteurs/admin/ </p>
<p>http://&lt;server&gt;:&lt;port&gt;/ecm/documents/admin/</td>
</tr>
<tr>
<td valign="top">Indexation / suppression</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/ecm/utilisteurs/update </p>
<p>http://&lt;server&gt;:&lt;port&gt;/ecm/documents/update</td>
</tr>
<tr>
<td valign="top">Recherche</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/ecm/utilisteurs/select  </p>
<p>http://&lt;server&gt;:&lt;port&gt;/ecm/documents/select</td>
</tr>
</tbody>
</table>
<p>Les urls d&#8217;accès à l&#8217;administration et aux web service Solr de l&#8217;application Forum sont :</p>
<table border="1">
<tbody>
<tr>
<td valign="top">Administration</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/forum/utilisteurs/admin/ </p>
<p>http://&lt;server&gt;:&lt;port&gt;/forum/messages/admin/</td>
</tr>
<tr>
<td valign="top">Indexation / suppression</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/forum/utilisteurs/update </p>
<p>http://&lt;server&gt;:&lt;port&gt;/forum/messages/update</td>
</tr>
<tr>
<td valign="top">Recherche</td>
<td valign="top">=&gt;</td>
<td valign="top">http://&lt;server&gt;:&lt;port&gt;/forum/utilisteurs/select  </p>
<p>http://&lt;server&gt;:&lt;port&gt;/forum/messages/select</td>
</tr>
</tbody>
</table>
<p>Sous Linux, une optimisation peut être de factoriser le répertoire &laquo;&nbsp;bin&nbsp;&raquo; de chaque core car il contient exactement les mêmes scripts. On place un répertoire &laquo;&nbsp;bin&nbsp;&raquo; dans &laquo;&nbsp;/opt/solr&nbsp;&raquo; et dans chaque core, on créer un lien symbolique nommé &laquo;&nbsp;bin&nbsp;&raquo; et qui pointe sur &laquo;&nbsp;/opt/solr/bin&nbsp;&raquo;.</p>
<p>Pour synthétiser les différents cas de figure lors du choix d&#8217;une configuration de Solr, voici un tableau récapitulatif.</p>
<table border="1">
<tbody>
<tr valign="top">
<td valign="top">Une seule application avec un seul type de données à indexer</td>
<td>=&gt;</td>
<td valign="top">1 webapp, pas de SolrCore</td>
</tr>
<tr valign="top">
<td>Une seule application avec plusieurs types de données très similaires. Par exemple, des articles de presse, des dossiers, des rapport, des études, &#8230; qui ont tous des meta-données communes (titre, auteur, date de publication et contenu)</td>
<td>=&gt;</td>
<td>1 webapp, pas de SolrCore mais une donnée qualifiant le type permettant le filtrage de la liste de résultat sur une ou plusieurs de ces valeurs.</td>
</tr>
<tr valign="top">
<td>Une seule application avec plusieurs types de données sans similarité (documents, utilisateurs, &#8230;)</td>
<td>=&gt;</td>
<td>1 webapp et des SolsCore pour indexer les différents types de données dans des index disctincts</td>
</tr>
<tr valign="top">
<td>Plusieurs applications (ECM, Forum, messagerie).</td>
<td>=&gt;</td>
<td>1 webapp par application avec ou sans SolrCore multiple en fonction des données à indexer pour chacune des applications (voir les cas précédents)</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.eolya.fr/2009/05/10/introduction-a-solr-installation-et-configuration-2/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

