<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Le Blog du Geek Joyeux</title>
  <subtitle>Plus moins vite tu codes, moins plus vite &#231;a plante</subtitle>
  <link href="http://blog.happynoff.fr/atom.xml" rel="self"/>
  <link href="http://blog.happynoff.fr" rel="alternate"/>
  <id>http://blog.happynoff.fr</id>
  <updated>2012-02-03T18:03:09Z</updated>
  <author>
    <name>Simon COURTOIS</name>
  </author>
  <entry>
    <title>D&#233;finir une ressource Active Admin dans une gem</title>
    <link href="http://blog.happynoff.fr/post/Definir-une-ressource-Active-Admin-dans-une-gem" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Definir-une-ressource-Active-Admin-dans-une-gem</id>
    <updated>2012-02-03T18:03:09Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Si vous utilisez &lt;a href='http://activeadmin.info/'&gt;Active Admin&lt;/a&gt; pour g&#233;n&#233;rer vos interfaces d&amp;#8217;administration sous Rails, voici une technique pour d&#233;finir des ressources depuis un engine.&lt;/p&gt;

&lt;h2 id='d&#233;finir_la_ressource'&gt;D&#233;finir la ressource&lt;/h2&gt;

&lt;p&gt;Pour une question de simplicit&#233;, je place mes ressources dans un dossier &lt;code&gt;admin&lt;/code&gt; situ&#233; dans le dossier &lt;code&gt;lib/my_engine&lt;/code&gt; de mon engine.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre class='ruby'&gt;&lt;span class='c'&gt;# lib/my_engine/admin/articles.rb&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;if&lt;/span&gt; &lt;span class='r'&gt;defined?&lt;/span&gt;(&lt;span class='co'&gt;ActiveAdmin&lt;/span&gt;)&lt;br&gt;  &lt;span class='co'&gt;ActiveAdmin&lt;/span&gt;.register &lt;span class='co'&gt;Article&lt;/span&gt; &lt;span class='r'&gt;do&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# personnalisez ici votre ressource&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='charger_la_ressource'&gt;Charger la ressource&lt;/h2&gt;

&lt;p&gt;Le probl&#232;me auquel j&amp;#8217;ai &#233;t&#233; confront&#233; au d&#233;but &#233;tait celui du chargement de cette ressource.&lt;/p&gt;

&lt;p&gt;Na&#239;vement, je l&amp;#8217;avais plac&#233;e dans &lt;code&gt;app/admin/articles.rb&lt;/code&gt; dans mon engine mais elle n&amp;#8217;&#233;tait pas charg&#233;e par l&amp;#8217;application. Je l&amp;#8217;ai ensuite plac&#233;e dans &lt;code&gt;lib/my_engine/admin&lt;/code&gt; et ai appel&#233; &lt;code&gt;require&lt;/code&gt; dessus. Le probl&#232;me est que le mod&#232;le &lt;code&gt;Article&lt;/code&gt; n&amp;#8217;&#233;tait pas encore d&#233;fini au moment de l&amp;#8217;appel &#224; &lt;code&gt;register&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;J&amp;#8217;ai donc fait appel &#224; &lt;code&gt;after_initialize&lt;/code&gt; dans la d&#233;finition de l&amp;#8217;engine:&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre class='ruby'&gt;&lt;span class='c'&gt;# lib/my_engine/engine.rb&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;module&lt;/span&gt; &lt;span class='cl'&gt;MyEngine&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;Engine&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;Rails&lt;/span&gt;::&lt;span class='co'&gt;Engine&lt;/span&gt;&lt;br&gt;    config.after_initialize &lt;span class='r'&gt;do&lt;/span&gt;&lt;br&gt;      require &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;my_engine/admin/articles&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Ce n&amp;#8217;est peut &#234;tre pas la solution la plus optimale ou la plus propre. Je serais d&amp;#8217;ailleurs ravi d&amp;#8217;avoir une solution alternative plus efficace. Celle-l&#224; a le m&#233;rite de fonctionner : ).&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>size doesn't COUNT</title>
    <link href="http://blog.happynoff.fr/post/size-doesn-t-COUNT" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/size-doesn-t-COUNT</id>
    <updated>2012-01-17T10:16:15Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;h2 id='requ&#234;tes_n1'&gt;Requ&#234;tes N+1&lt;/h2&gt;

&lt;p&gt;Lorsque vous d&#233;veloppez avec Rails, vous devez bien s&#251;r faire attention aux requ&#234;tes qui sont effectu&#233;es et surtout &#233;viter les requ&#234;tes &lt;em&gt;N+1&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Les requ&#234;tes &lt;em&gt;N+1&lt;/em&gt; sont celles qui sont lanc&#233;es pour chaque &#233;l&#233;ment d&amp;#8217;une liste.&lt;/p&gt;

&lt;p&gt;Prenons l&amp;#8217;exemple suivant :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre class='ruby'&gt;&lt;span class='c'&gt;# Dans le contr&#244;leur&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='iv'&gt;@articles&lt;/span&gt; = &lt;span class='co'&gt;Article&lt;/span&gt;.all&lt;br&gt;&lt;span class='c'&gt;# SELECT articles.* FROM articles&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;# Dans la vue&lt;/span&gt;&lt;br&gt;&lt;br&gt;&amp;lt;&lt;span class='s'&gt;&lt;span class='dl'&gt;% &lt;/span&gt;&lt;span class='k'&gt;@articles.each&lt;/span&gt;&lt;span class='dl'&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class='r'&gt;do&lt;/span&gt; |article| &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&lt;br&gt;  ...&lt;br&gt;  Nombre de commentaires: &amp;lt;%= articles.comments.count %&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='c'&gt;# SELECT COUNT(*) FROM comments WHERE comments.article_id = XY&lt;/span&gt;&lt;br&gt;  ...&lt;br&gt;&amp;lt;&lt;span class='s'&gt;&lt;span class='dl'&gt;% &lt;/span&gt;&lt;span class='k'&gt;end&lt;/span&gt;&lt;span class='dl'&gt; &lt;/span&gt;&lt;/span&gt;%&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pour chaque article list&#233;, une requ&#234;te va &#234;tre lanc&#233;e pour compter ses commentaires.&lt;/p&gt;

&lt;p&gt;Heureusement pour nous, Rails fournit, dans l&amp;#8217;API d&amp;#8217;ActiveRecord un moyen d&amp;#8217;&#233;viter ces requ&#234;tes &lt;em&gt;N+1&lt;/em&gt;. Il s&amp;#8217;agit de la m&#233;thode &lt;code&gt;includes&lt;/code&gt; qui s&amp;#8217;utilise comme ceci :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre class='ruby'&gt;&lt;span class='iv'&gt;@articles&lt;/span&gt; = &lt;span class='co'&gt;Article&lt;/span&gt;.includes(&lt;span class='sy'&gt;:comments&lt;/span&gt;).all&lt;br&gt;&lt;span class='c'&gt;# SELECT articles.* FROM articles&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# SELECT comments.* FROM comments WHERE comments.article_id IN (1, 2, ..., 42)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On peut donc voir ici que l&amp;#8217;ensemble des commentaires est r&#233;cup&#233;r&#233; d&amp;#8217;un seul coup. Cela nous permet d&amp;#8217;acc&#233;der aux informations des commentaires d&amp;#8217;un article sans requ&#234;te suppl&#233;mentaire.&lt;/p&gt;

&lt;h2 id='size_vs_count'&gt;Size vs. Count&lt;/h2&gt;

&lt;p&gt;Le souci c&amp;#8217;est que &#231;a ne r&#232;gle pas notre probl&#232;me de &lt;code&gt;count&lt;/code&gt;. En effet, si nous faisons de nouveau appel &#224; count, les requ&#234;tes seront tout de m&#234;me effectu&#233;es !&lt;/p&gt;

&lt;p&gt;L&amp;#8217;astuce est donc d&amp;#8217;utiliser &lt;code&gt;size&lt;/code&gt; plut&#244;t que &lt;code&gt;count&lt;/code&gt; sur l&amp;#8217;attribut &lt;code&gt;comments&lt;/code&gt; de nos articles, ce qui va simplement retourner la taille du tableau contenant les commentaires associ&#233;s. Ces derniers &#233;tant d&#233;j&#224; charg&#233;s, le compte est bon !&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre class='ruby'&gt;&lt;span class='c'&gt;# Dans le contr&#244;leur&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='iv'&gt;@articles&lt;/span&gt; = &lt;span class='co'&gt;Article&lt;/span&gt;.includes(&lt;span class='sy'&gt;:comments&lt;/span&gt;).all&lt;br&gt;&lt;span class='c'&gt;# SELECT articles.* FROM articles&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# SELECT comments.* FROM comments WHERE comments.article_id IN (1, 2, ..., 42)&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;# Dans la vue&lt;/span&gt;&lt;br&gt;&lt;br&gt;&amp;lt;&lt;span class='s'&gt;&lt;span class='dl'&gt;% &lt;/span&gt;&lt;span class='k'&gt;@articles.each&lt;/span&gt;&lt;span class='dl'&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class='r'&gt;do&lt;/span&gt; |article| &lt;span class='s'&gt;&lt;span class='dl'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;&lt;br&gt;  ...&lt;br&gt;  Nombre de commentaires: &amp;lt;%= articles.comments.size %&lt;/span&gt;&lt;span class='dl'&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  ...&lt;br&gt;&amp;lt;&lt;span class='s'&gt;&lt;span class='dl'&gt;% &lt;/span&gt;&lt;span class='k'&gt;end&lt;/span&gt;&lt;span class='dl'&gt; &lt;/span&gt;&lt;/span&gt;%&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Versionner ses scripts de seeding avec versioned_seeds</title>
    <link href="http://blog.happynoff.fr/post/Versionner-ses-scripts-de-seeding-avec-versioned_seeds" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Versionner-ses-scripts-de-seeding-avec-versioned_seeds</id>
    <updated>2011-12-07T21:30:47Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Si vous vous retrouvez dans le besoin de faire des imports de donn&#233;es ou des insertions script&#233;es dans une application Rails, de nos jours vous n&amp;#8217;avez pas vraiment d&amp;#8217;autre choix que de cr&#233;er des t&#226;ches rake (ou consorts) pour le faire.&lt;/p&gt;

&lt;p&gt;Dans cette id&#233;e, j&amp;#8217;ai &#233;crit la gem &lt;a href='https://github.com/simonc/versioned_seeds'&gt;versioned_seeds&lt;/a&gt; qui permet de stocker ces scripts dans un dossier sp&#233;cifique et de les utiliser &#224; la mani&#232;re des migrations.&lt;/p&gt;

&lt;p&gt;Son installation se fait gr&#226;ce &#224; l&amp;#8217;ajout de la ligne suivante dans votre &lt;code&gt;Gemfile&lt;/code&gt;&#160;:&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre class='ruby'&gt;gem &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;versioned_seeds&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class='ke'&gt;require&lt;/span&gt;: &lt;span class='pc'&gt;false&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Le principe est simple, vous appelez un g&#233;n&#233;rateur qui va cr&#233;er au besoin le dossier et un script dans celui ci. Le nom du script commence par un timestamp, comme les migrations, ce qui va permettre &#224; versioned_seeds de l&amp;#8217;enregistrer et de ne pas l&amp;#8217;ex&#233;cuter plusieurs fois.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rails g versioned_seeds:seed_file nom_du_script&lt;br&gt;        create db/seeds&lt;br&gt;        create db/seeds/20111207201942_nom_du_script.rb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Vous n&amp;#8217;avez plus qu&amp;#8217;&#224; &#233;crire votre script puis, une fois termin&#233;, &#224; appeler une t&#226;che rake qui va l&amp;#8217;ex&#233;cuter:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rake vs:next&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cette t&#226;che va trouv&#233; le prochain script non charg&#233; jusqu&amp;#8217;&#224; pr&#233;sent et le lancer. Si vous avez g&#233;n&#233;r&#233; plusieurs scripts, vous pouvez faire appel &#224;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rake vs:all&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Qui va les lancer un-&#224;-un.&lt;/p&gt;

&lt;p&gt;Pour savoir o&#249; vous en &#234;tes de vos scripts, vous pouvez faire appel &#224;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rake vs:status&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pour connaitre la version du dernier script charg&#233;.&lt;/p&gt;

&lt;p&gt;Pensez simplement &#224; ignorer le fichier .versioned_seeds dans Git, il sert &#224; stocker la liste des scripts d&#233;j&#224; lanc&#233;s et il ne doit pas &#234;tre versionn&#233; puisqu&amp;#8217;il est sp&#233;cifique &#224; chaque machine.&lt;/p&gt;

&lt;p&gt;Le code est disponible sur &lt;a href='https://github.com/simonc/versioned_seeds'&gt;Github&lt;/a&gt; et la gem sur &lt;a href='https://rubygems.org/gems/versioned_seeds'&gt;rubygems.org&lt;/a&gt;.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Utiliser rvm avec cron</title>
    <link href="http://blog.happynoff.fr/post/Utiliser-rvm-avec-cron" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Utiliser-rvm-avec-cron</id>
    <updated>2011-09-24T05:40:12Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Il y a quelques temps, j&amp;#8217;avais besoin de lancer un script ruby avec cron. Le souci, c&amp;#8217;est que sur mon serveur, tout est &#224; base de rvm. De fait, cron ne sait pas trouver ruby puisque rvm est charg&#233; par mon fichier &lt;em&gt;.bashrc&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;La petite astuce pour que &#231;a marche, c&amp;#8217;est de dire &#224; cron de charger mon environnement pour ce script sp&#233;cifiquement :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre class='cron'&gt;0 * * * * /bin/bash -l -c 'ruby mon_script.rb'&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;En clair, l&amp;#8217;option &lt;em&gt;-l&lt;/em&gt; permet de charger l&amp;#8217;environnement bash et l&amp;#8217;option &lt;em&gt;-c&lt;/em&gt; indique la commande &#224; ex&#233;cuter.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Rendre git-diff plus pr&#233;cis</title>
    <link href="http://blog.happynoff.fr/post/Rendre-git-diff-plus-precis" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Rendre-git-diff-plus-precis</id>
    <updated>2011-09-19T23:46:35Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Git permet d&amp;#8217;afficher diff&#233;rentes informations en couleur. Cela se fait dans le fichier de configuration, &lt;em&gt;~/.gitconfig&lt;/em&gt;.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre class='ini'&gt;[color]&lt;br&gt;  ui = true&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Une des commandes concern&#233;es est &lt;em&gt;git-diff&lt;/em&gt;. Cette coloration est bien pratique mais peut avoir ses limites. En effet, lorsque la diff&#233;rence sur une ligne se joue &#224; quelques caract&#232;res seulement, il peut &#234;tre difficile de d&#233;tecter les modifications.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre class='diff'&gt;&lt;span class='c'&gt;  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,&lt;/span&gt;&lt;br&gt;&lt;span class='line del'&gt;&lt;span class='del'&gt;-&lt;/span&gt; quis nostrud exercitation ullamco labaris nisi ut aliquip ex ea commodo&lt;/span&gt;&lt;br&gt;&lt;span class='line ins'&gt;&lt;span class='ins'&gt;+&lt;/span&gt; quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;  non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Une petite astuce pour les voir plus pr&#233;cis&#233;ment est l&amp;#8217;utilisation de l&amp;#8217;option &lt;em&gt;&amp;#8211;word-diff&lt;/em&gt;&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre class='bash'&gt;git diff --word-diff=color&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Voici le r&#233;sultat obtenu :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;pre class='diff'&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod&lt;br&gt;tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,&lt;br&gt;quis nostrud exercitation ullamco lab&lt;span class='del'&gt;o&lt;/span&gt;&lt;span class='ins'&gt;a&lt;/span&gt;ris nisi ut aliquip ex ea commodo&lt;br&gt;consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse&lt;br&gt;cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat&lt;br&gt;non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;L&amp;#8217;option prend diff&#233;rentes valeurs qui peuvent &#234;tre utiles selon les circonstances.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Gestion du PATH sous OS X</title>
    <link href="http://blog.happynoff.fr/post/Gestion-du-PATH-sous-OS-X" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Gestion-du-PATH-sous-OS-X</id>
    <updated>2011-09-19T23:44:06Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Une fonctionnalit&#233; bien pratique de &lt;em&gt;OS&lt;/em&gt;X_ est la gestion du PATH. En effet un m&#233;canisme permet de ne pas surcharger son &lt;em&gt;.bashrc&lt;/em&gt; chaque fois que l&amp;#8217;on doit rajouter une entr&#233;e dans le PATH.&lt;/p&gt;

&lt;p&gt;La magie s&amp;#8217;op&#232;re dans le fichier &lt;em&gt;/etc/paths&lt;/em&gt; et dans le dossier &lt;em&gt;/etc/paths.d&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Le premier est un listing des chemin g&#233;n&#233;raux :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;/usr/bin&lt;br&gt;/bin&lt;br&gt;/usr/sbin&lt;br&gt;/sbin&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Le deuxi&#232;me est un dossier permettant d&amp;#8217;ajouter des fichiers contenant des listings en plus. Ces fichiers seront charg&#233;s &#224; la suite de &lt;em&gt;/etc/paths&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id='exemple'&gt;Exemple&lt;/h2&gt;

&lt;p&gt;Si vous avez install&#233; MySQL avec le DMG fourni sur le site officiel, vous pouvez ajouter le chemin des ex&#233;cutables mysql en cr&#233;ant un fichier &lt;em&gt;/etc/paths.d/mysql&lt;/em&gt; et y &#233;crire la ligne suivante :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;/usr/local/mysql/bin&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='collision'&gt;Collision&lt;/h2&gt;

&lt;p&gt;Si vous vous trouvez dans la situation o&#249; vous avez un ex&#233;cutable dans un dossier non syst&#232;me et que vous souhaitez que ce dossier ait la priorit&#233;, mettez le en t&#234;te du fichier &lt;em&gt;/etc/paths&lt;/em&gt;, les chemins sont charg&#233;s dans l&amp;#8217;ordre.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Cr&#233;er ses propres s&#233;lecteurs avec jQuery</title>
    <link href="http://blog.happynoff.fr/post/Creer-ses-propres-selecteurs-avec-jQuery" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Creer-ses-propres-selecteurs-avec-jQuery</id>
    <updated>2011-08-25T15:03:01Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Il y a peu, au boulot, on s&amp;#8217;est demand&#233; si, avec jQuery, il &#233;tait possible de s&#233;lectionner les &#233;l&#233;ments dont une classe correspond &#224; mod&#232;le donn&#233;.&lt;/p&gt;

&lt;p&gt;Par exemple, s&#233;lectionner tous ceux donc la classe commence par &lt;em&gt;menu_item_&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;La r&#233;ponse est oui, avec jQuery, c&amp;#8217;est possible. Voici comment.&lt;/p&gt;    </summary>
    <content type="html">
&lt;p&gt;Ce que nous cherchons &#224; obtenir, c&amp;#8217;est quelque chose dans ce go&#251;t l&#224;&amp;#160;:&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='pd'&gt;$&lt;/span&gt;(&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;li:classMatch(^menu_item_)&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Il faut en fait cr&#233;er un s&#233;lecteur personnalis&#233;. Cela se fait en d&#233;finissant une fonction afin d&amp;#8217;&#233;tendre les s&#233;lecteurs standards de jQuery&amp;#160;:&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='pd'&gt;$&lt;/span&gt;.expr[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;].&lt;span class='fu'&gt;nomDuFiltre&lt;/span&gt; = &lt;span class='kw'&gt;function&lt;/span&gt;(obj, index, meta, stack) {&lt;br&gt;  &lt;span class='c'&gt;// ...&lt;/span&gt;&lt;br&gt;};&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Si votre fonction retourne &lt;em&gt;vrai&lt;/em&gt; l&amp;#8217;&#233;l&#233;ment est s&#233;lectionn&#233;, sinon il est rejet&#233;. La fonction re&#231;oit quatre arguments&amp;#160;:&lt;/p&gt;

&lt;dl&gt;
&lt;dt&gt;obj&lt;/dt&gt;

&lt;dd&gt;l&amp;#8217;&#233;l&#233;ment DOM &#224; tester&lt;/dd&gt;

&lt;dt&gt;index&lt;/dt&gt;

&lt;dd&gt;le num&#233;ro d&amp;#8217;it&#233;ration dans la boucle&lt;/dd&gt;

&lt;dt&gt;meta&lt;/dt&gt;

&lt;dd&gt;les meta-donn&#233;es de votre s&#233;lecteur (dont les arguments)&lt;/dd&gt;

&lt;dt&gt;stack&lt;/dt&gt;

&lt;dd&gt;la pile de tous les &#233;l&#233;ments &#224; tester&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;Les deux arguments qui vont nous int&#233;resser sont &lt;em&gt;obj&lt;/em&gt; et &lt;em&gt;meta&lt;/em&gt;. Si on regarde le contenu de l&amp;#8217;argument &lt;em&gt;meta&lt;/em&gt;, on trouve ceci&amp;#160;:&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;[ &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;:classMatch(^menu_item_)&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class='c'&gt;// 0&lt;/span&gt;&lt;br&gt;  &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,                        &lt;span class='c'&gt;// 1&lt;/span&gt;&lt;br&gt;  &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;classMatch&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,               &lt;span class='c'&gt;// 2&lt;/span&gt;&lt;br&gt;  &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;^menu_item_&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,              &lt;span class='c'&gt;// 3&lt;/span&gt;&lt;br&gt;  &lt;span class='pc'&gt;undefined&lt;/span&gt; ]                 &lt;span class='c'&gt;// 4&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;L&amp;#8217;entr&#233;e qui nous int&#233;resse est donc stock&#233;e dans &lt;em&gt;meta&lt;span&gt;3&lt;/span&gt;&lt;/em&gt;. Il ne nous reste donc plus qu&amp;#8217;&#224; tester si une des classes de notre &#233;l&#233;ment correspond &#224; la valeur pass&#233;e et &#224; retourner vrai si tel est le cas&amp;#160;:&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='pd'&gt;$&lt;/span&gt;.expr[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;:&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;].&lt;span class='fu'&gt;classMatch&lt;/span&gt; = &lt;span class='kw'&gt;function&lt;/span&gt;(obj, index, meta, stack) {&lt;br&gt;  &lt;span class='kw'&gt;var&lt;/span&gt; pattern = &lt;span class='kw'&gt;new&lt;/span&gt; RegExp(meta[&lt;span class='i'&gt;3&lt;/span&gt;]);&lt;br&gt;  &lt;span class='kw'&gt;var&lt;/span&gt; classes = obj.className.split(&lt;span class='rx'&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;span class='ch'&gt;\s&lt;/span&gt;&lt;span class='k'&gt;+&lt;/span&gt;&lt;span class='dl'&gt;/&lt;/span&gt;&lt;/span&gt;);&lt;br&gt;  &lt;span class='kw'&gt;var&lt;/span&gt; found   = &lt;span class='pc'&gt;false&lt;/span&gt;;&lt;br&gt;&lt;br&gt;  &lt;span class='pd'&gt;$&lt;/span&gt;.each(classes, &lt;span class='kw'&gt;function&lt;/span&gt;() {&lt;br&gt;    found = &lt;span class='lv'&gt;this&lt;/span&gt;.match(pattern);&lt;br&gt;    &lt;span class='kw'&gt;return&lt;/span&gt; !found;&lt;br&gt;  });&lt;br&gt;&lt;br&gt;  &lt;span class='kw'&gt;return&lt;/span&gt; found;&lt;br&gt;};&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Nous pouvons maintenant utiliser notre nouveau s&#233;lecteur pour trouver les &#233;l&#233;ments qui nous int&#233;ressent.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Installation de markItUp avec preview dans une application Rails3</title>
    <link href="http://blog.happynoff.fr/post/Installation-de-markItUp-avec-preview-dans-une-application-Rails3" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Installation-de-markItUp-avec-preview-dans-une-application-Rails3</id>
    <updated>2011-08-25T15:03:01Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Il est fr&#233;quent d&amp;#8217;avoir besoin d&amp;#8217;un &#233;diteur dit WYSIWYG dans un site web. Il en existe de deux types. Les &#233;diteurs pur WYSIWYG o&#249; vous &#233;ditez directement du HTML en mode rendu final et les &#233;diteurs de syntaxe qui se basent par exemple sur le format &lt;a href='http://en.wikipedia.org/wiki/Help:Wiki_markup'&gt;Wiki&lt;/a&gt;, &lt;a href='http://www.textism.com/tools/textile/'&gt;Textile&lt;/a&gt; ou &lt;a href='http://daringfireball.net/projects/markdown/'&gt;Markdown&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://markitup.jaysalvat.com/home/'&gt;markItUp&lt;/a&gt; est de la deuxi&#232;me cat&#233;gorie. Dans le cas d&amp;#8217;un &#233;diteur de syntaxe, il est toujours plus confortable de disposer d&amp;#8217;une preview avant de valider ce qu&amp;#8217;on a &#233;crit.&lt;/p&gt;

&lt;p&gt;Voici un petit tutoriel sur comment installer markItUp dans une appli &lt;a href='http://rubyonrails.org/'&gt;Rails3&lt;/a&gt; en utilisant &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra&lt;/a&gt; pour g&#233;n&#233;rer la preview.&lt;/p&gt;    </summary>
    <content type="html">
&lt;p&gt;Pour ce tutoriel, je choisirai la syntaxe markdown et mon moteur de transformation de markdown vers HTML sera &lt;a href='https://github.com/rtomayko/rdiscount/'&gt;RDiscount&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='pr&#233;requis'&gt;Pr&#233;requis&lt;/h2&gt;

&lt;p&gt;&lt;a href='http://markitup.jaysalvat.com/home/'&gt;markItUp&lt;/a&gt; se base sur &lt;a href='http://jquery.com/'&gt;jQuery&lt;/a&gt;, vous aurez donc besoin d&amp;#8217;une application Rails utilisant &lt;a href='https://github.com/rails/jquery-rails'&gt;jquery-rails&lt;/a&gt;. Je ne d&#233;taillerai pas ici la proc&#233;dure d&amp;#8217;installation qui est relativement simple et tr&#232;s bien expliqu&#233;e sur &lt;a href='https://github.com/rails/jquery-rails'&gt;la page github de jquery-rails&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='installation_de_markitup'&gt;Installation de markItUp&lt;/h2&gt;

&lt;p&gt;Commencez par t&#233;l&#233;charger la derni&#232;re version de markItUp depuis le &lt;a href='http://markitup.jaysalvat.com/home/'&gt;site officiel&lt;/a&gt;. Sauvez l&amp;#8217;archive dans &lt;em&gt;RAILS&lt;/em&gt;ROOT/public/javascripts/_. D&#233;compressez la et d&#233;placez le dossier &lt;em&gt;RAILS&lt;/em&gt;ROOT/public/javascripts/latest/markitup_ dans &lt;em&gt;RAILS&lt;/em&gt;ROOT/public/javascripts/markitup_. Vous pouvez ensuite supprimer &lt;em&gt;latest&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Pour r&#233;cup&#233;rer les &lt;abbr title='Cascading StyleSheet'&gt;CSS&lt;/abbr&gt; et images contenues dans &lt;em&gt;markitup&lt;/em&gt;, le plus simple est de cr&#233;er un lien symbolique vers &lt;em&gt;markitup&lt;/em&gt; dans &lt;em&gt;public/images&lt;/em&gt; et &lt;em&gt;public/stylesheets&lt;/em&gt;.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='fu'&gt;cd&lt;/span&gt; RAILS_ROOT/public/images&lt;br&gt;ln -s ../javascripts/markitup ./&lt;br&gt;&lt;br&gt;&lt;span class='fu'&gt;cd&lt;/span&gt; RAILS_ROOT/public/stylesheets&lt;br&gt;ln -s ../javascripts/markitup ./&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Vous aurez ensuite besoin d&amp;#8217;un set pour g&#233;rer Markdown. Il en existe plusieurs. Mon choix se portera ici sur &lt;a href='http://markitup.jaysalvat.com/downloads/demo.php?id=markupsets/markmin'&gt;Markmin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;T&#233;l&#233;chargez son archive et d&#233;compressez la dans &lt;em&gt;markitup/sets/&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Une fois cela fait, il faut ajouter les balises qui vont bien dans le layout de l&amp;#8217;application.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='ta'&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='ta'&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Ma super appli Rails 3&lt;span class='ta'&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='ta'&gt;&amp;lt;meta&lt;/span&gt; &lt;span class='an'&gt;http-equiv&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;Content-Type&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class='an'&gt;content&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;text/html; charset=utf-8&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class='ta'&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='il'&gt;&lt;span class='idl'&gt;&amp;lt;%=&lt;/span&gt; stylesheet_link_tag &lt;span class='sy'&gt;:all&lt;/span&gt; &lt;span class='idl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class='il'&gt;&lt;span class='idl'&gt;&amp;lt;%=&lt;/span&gt; stylesheet_link_tag &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;markitup/skins/simple/style.css&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='idl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='il'&gt;&lt;span class='idl'&gt;&amp;lt;%=&lt;/span&gt; stylesheet_link_tag &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;markitup/sets/markmin/style.css&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='idl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class='il'&gt;&lt;span class='idl'&gt;&amp;lt;%=&lt;/span&gt; javascript_include_tag &lt;span class='sy'&gt;:defaults&lt;/span&gt; &lt;span class='idl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='il'&gt;&lt;span class='idl'&gt;&amp;lt;%=&lt;/span&gt; javascript_include_tag &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;markitup/jquery.markitup.js&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='idl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='il'&gt;&lt;span class='idl'&gt;&amp;lt;%=&lt;/span&gt; javascript_include_tag &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;markitup/sets/markmin/set.js&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='idl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class='il'&gt;&lt;span class='idl'&gt;&amp;lt;%=&lt;/span&gt; csrf_meta_tag &lt;span class='idl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class='ta'&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On r&#233;cup&#232;re donc la &lt;abbr title='Cascading StyleSheet'&gt;CSS&lt;/abbr&gt; du style Simple de &lt;a href='http://markitup.jaysalvat.com/home/'&gt;markItUp&lt;/a&gt; ainsi que celle sp&#233;cifique &#224; Markmin. De la m&#234;me mani&#232;re, on r&#233;cup&#232;re le script de &lt;a href='http://markitup.jaysalvat.com/home/'&gt;markItUp&lt;/a&gt; et le set sp&#233;cifique &#224; Markdown.&lt;/p&gt;

&lt;h2 id='mise_en_place_de_markitup_sur_une_textarea'&gt;Mise en place de markItUp sur une textarea&lt;/h2&gt;

&lt;p&gt;Pour activer markItUp sur une textarea, cela se fait de mani&#232;re tr&#232;s simple. Le set activ&#233; fournit de base une variable mySettings que vous pouvez utiliser telle quelle ou modifier &#224; votre convenance.&lt;/p&gt;

&lt;p&gt;Dans public/javascripts/application.js, ajoutez le code suivant :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='pd'&gt;$&lt;/span&gt;(&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;textarea.markItUp&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;).markItUp(mySettings);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Lorsque vous voulez activer &lt;a href='http://markitup.jaysalvat.com/home/'&gt;markItUp&lt;/a&gt;, ajoutez la classe &lt;em&gt;markItUp&lt;/em&gt; sur la textarea de votre choix :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='il'&gt;&lt;span class='idl'&gt;&amp;lt;%=&lt;/span&gt; f.text_area &lt;span class='sy'&gt;:content&lt;/span&gt;, &lt;span class='sy'&gt;:class&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;markItUp&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='idl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='mise_en_place_du_syst&#232;me_de_preview_avec_sinatra'&gt;Mise en place du syst&#232;me de preview avec Sinatra&lt;/h2&gt;

&lt;p&gt;Pour commencer, nous allons ajouter &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra&lt;/a&gt; et &lt;a href='https://github.com/rtomayko/rdiscount/'&gt;RDiscount&lt;/a&gt; dans notre &lt;em&gt;Gemfile&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;gem &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;sinatra&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;br&gt;gem &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;rdiscount&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Installons nos nouvelles gems gr&#226;ce &#224; l&amp;#8217;ami &lt;a href='http://gembundler.com/'&gt;Bundler&lt;/a&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;bundle&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&#201;crivons ensuite notre application &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra&lt;/a&gt; qui va nous demander un long travail. Vous &#234;tes pr&#234;t ? C&amp;#8217;est parti !&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='c'&gt;# RAILS_ROOT/lib/markitup_preview.rb&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;MarkitupPreview&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;Sinatra&lt;/span&gt;::&lt;span class='co'&gt;Base&lt;/span&gt;&lt;br&gt;  post &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;/markitup-preview&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='r'&gt;do&lt;/span&gt;&lt;br&gt;    &lt;span class='co'&gt;RDiscount&lt;/span&gt;.new(params[&lt;span class='sy'&gt;:code&lt;/span&gt;]).to_html&lt;br&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Hop, termin&#233; ! C&amp;#8217;est tout&amp;#8230; Bon maintenant, il faut faire en sorte que notre application soit atteignable au travers de Rails. Commen&#231;ons par inclure le fichier &lt;em&gt;markitup&lt;/em&gt;preview.rb_ dans &lt;em&gt;config/application.rb&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='co'&gt;Bundler&lt;/span&gt;.require(&lt;span class='sy'&gt;:default&lt;/span&gt;, &lt;span class='co'&gt;Rails&lt;/span&gt;.env) &lt;span class='r'&gt;if&lt;/span&gt; &lt;span class='r'&gt;defined?&lt;/span&gt;(&lt;span class='co'&gt;Bundler&lt;/span&gt;)&lt;br&gt;&lt;br&gt;require &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;lib/markitup_preview&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='r'&gt;module&lt;/span&gt; &lt;span class='cl'&gt;MyRailsApp&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;Application&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;Rails&lt;/span&gt;::&lt;span class='co'&gt;Application&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Il nous faut &#233;galement ajouter la route Rails menant &#224; notre application :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='c'&gt;# RAILS_ROOT/config/routes.rb&lt;/span&gt;&lt;br&gt;post &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;markitup-preview&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class='co'&gt;MarkitupPreview&lt;/span&gt;, &lt;span class='sy'&gt;:format&lt;/span&gt; =&amp;gt; &lt;span class='pc'&gt;false&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='contacter_le_syst&#232;me_de_preview_depuis_le_javascript'&gt;Contacter le syst&#232;me de preview depuis le JavaScript&lt;/h2&gt;

&lt;p&gt;Il nous faut retourner dans &lt;em&gt;application.js&lt;/em&gt; et personnaliser notre &lt;em&gt;mySettings&lt;/em&gt;.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;mySettings[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;previewParserPath&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;] = &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;/markitup-preview&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;br&gt;mySettings[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;previewParserVar&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;]  = &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;code&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;br&gt;&lt;br&gt;mySettings[&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;markupSet&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;].push({&lt;br&gt;  &lt;span class='ke'&gt;name&lt;/span&gt;:       &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;Preview&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;br&gt;  &lt;span class='ke'&gt;className&lt;/span&gt;:  &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;preview&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;br&gt;  &lt;span class='ke'&gt;call&lt;/span&gt;:       &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;preview&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;br&gt;)};&lt;br&gt;&lt;br&gt;&lt;span class='pd'&gt;$&lt;/span&gt;(&lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;textarea.markItUp&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;).markItUp(mySettings);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;On a un syst&#232;me fonctionnel de preview. Par dessus tout, on a &#233;vit&#233; de cr&#233;er un contr&#244;leur qui aurait eu pour seule utilit&#233; de faire cette preview. Cool !&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>La m&#233;thode inject en Ruby</title>
    <link href="http://blog.happynoff.fr/post/La-methode-inject-en-Ruby" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/La-methode-inject-en-Ruby</id>
    <updated>2011-08-25T15:03:00Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;En Ruby, il existe une m&#233;thode bien pratique nomm&#233;e &lt;em&gt;inject&lt;/em&gt;. Elle s&amp;#8217;utilise de la mani&#232;re suivante :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;puts (&lt;span class='i'&gt;0&lt;/span&gt;..&lt;span class='i'&gt;10&lt;/span&gt;).inject(&lt;span class='i'&gt;0&lt;/span&gt;) &lt;span class='r'&gt;do&lt;/span&gt; |somme, x|&lt;br&gt;  somme += x&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; 55&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Dans l&amp;#8217;exemple pr&#233;c&#233;dent, on part d&amp;#8217;une valeur de &lt;em&gt;0&lt;/em&gt; que l&amp;#8217;on modifie &#224; chaque tour. Le code suivant est &#233;quivalent :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;somme = &lt;span class='i'&gt;0&lt;/span&gt;&lt;br&gt;(&lt;span class='i'&gt;0&lt;/span&gt;..&lt;span class='i'&gt;10&lt;/span&gt;).each &lt;span class='r'&gt;do&lt;/span&gt; |x|&lt;br&gt;  somme += x&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;puts somme&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; 55&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;De mani&#232;re classique, on peut s&amp;#8217;en servire pour g&#233;n&#233;rer un tableau ou une table de hash de la mani&#232;re suivante :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='iv'&gt;@articles&lt;/span&gt;.inject({}) &lt;span class='r'&gt;do&lt;/span&gt; |hash, article|&lt;br&gt;  hash[article.title] = article.body&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Une autre utilisation interessante, est avec les bool&#233;ens :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='iv'&gt;@plugins&lt;/span&gt;.inject(&lt;span class='pc'&gt;true&lt;/span&gt;) &lt;span class='r'&gt;do&lt;/span&gt; |keep_going, plugin|&lt;br&gt;  keep_going &amp;amp;= plugin.some_method&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On obtient donc en fin de parcours, &lt;em&gt;true&lt;/em&gt; si tous les appels ont retourn&#233; &lt;em&gt;true&lt;/em&gt; ou &lt;em&gt;false&lt;/em&gt; si au moins un appel a retourn&#233; &lt;em&gt;false&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Dans le cas o&#249; on veut stoper l&amp;#8217;appel &#224; &lt;em&gt;inject&lt;/em&gt; d&#233;s qu&amp;#8217;un appel retourne &lt;em&gt;false&lt;/em&gt;, on peut utiliser l&amp;#8217;instruction &lt;em&gt;break&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='iv'&gt;@plugins&lt;/span&gt;.inject(&lt;span class='pc'&gt;true&lt;/span&gt;) &lt;span class='r'&gt;do&lt;/span&gt; |keep_going, plugin|&lt;br&gt;  keep_going &amp;amp;= plugin.some_method &lt;span class='r'&gt;or&lt;/span&gt; &lt;span class='r'&gt;break&lt;/span&gt;(keep_going)&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Cela permet de ne pas faire les appels suivants d&#233;s le premier retour n&#233;gatif.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>&#201;viter la cr&#233;ation des fichiers ._ (point underscore) sous Mac OS X</title>
    <link href="http://blog.happynoff.fr/post/eviter-point-underscore-sous-mac-os-x" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/eviter-point-underscore-sous-mac-os-x</id>
    <updated>2011-08-25T15:03:00Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Un comportement plut&#244;t g&#234;nant sous &lt;em&gt;OS X&lt;/em&gt; est la cr&#233;ation des fichiers ._ (point underscore). C&amp;#8217;est souvent un probl&#232;me quand on veut cr&#233;er une archive &lt;em&gt;.tar.gz&lt;/em&gt; ou avec certains &lt;em&gt;&lt;abbr title='Source Control Manager'&gt;SCM&lt;/abbr&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Voici une solution pour emp&#234;cher leur cr&#233;ation.&lt;/p&gt;

&lt;p&gt;Dans votre .bashrc et votre .profile, ajoutez la ligne suivante :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='fu'&gt;export&lt;/span&gt; &lt;span class='iv'&gt;COPYFILE_DISABLE&lt;/span&gt;=true&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Utiliser un shell non standard sous mac</title>
    <link href="http://blog.happynoff.fr/post/Utiliser-un-shell-non-standard-sous-mac" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Utiliser-un-shell-non-standard-sous-mac</id>
    <updated>2011-08-25T15:03:00Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Chaque fois que j&amp;#8217;installe un shell sous &lt;em&gt;Mac OS X&lt;/em&gt; et que je le r&#232;gle par d&#233;faut gr&#224;ce &#224; &lt;em&gt;chsh&lt;/em&gt;, l&amp;#8217;application &lt;em&gt;Terminal&lt;/em&gt; refuse de se lancer et me dit :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vous n&amp;#8217;&#234;tes pas autoris&#233; &#224; lancer cette application.&lt;/strong&gt;&lt;br /&gt;L&amp;#8217;administrateur a donn&#233; &#224; votre shell une valeur ill&#233;gale.&lt;/p&gt;

&lt;p&gt;Pour r&#233;gler ce petit souci, il suffit d&amp;#8217;ajouter le chemin vers votre shell dans le fichier &lt;em&gt;/etc/shells&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;cat /etc/shells&lt;br&gt;&lt;span class='c'&gt;# List of acceptable shells for chpass(1).&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# Ftpd will not allow users to connect who are not using&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# one of these shells.&lt;/span&gt;&lt;br&gt;&lt;br&gt;/usr/&lt;span class='fu'&gt;local&lt;/span&gt;/bin/bash &lt;span class='c'&gt;# bash install&#233; avec homebrew&lt;/span&gt;&lt;br&gt;/bin/bash&lt;br&gt;/bin/csh&lt;br&gt;/bin/ksh&lt;br&gt;/bin/sh&lt;br&gt;/bin/tcsh&lt;br&gt;/bin/zsh&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;C&amp;#8217;est une erreur que l&amp;#8217;on ne rencontre pas lorsque l&amp;#8217;on utilise un terminal comme &lt;a href='http://sites.google.com/site/iterm2home/'&gt;iTerm 2&lt;/a&gt;&amp;#8230;&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Utiliser la sortie d'une commande comme un fichier en shell</title>
    <link href="http://blog.happynoff.fr/post/Utiliser-la-sortie-d-une-commande-comme-un-fichier-en-shell" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Utiliser-la-sortie-d-une-commande-comme-un-fichier-en-shell</id>
    <updated>2011-08-25T15:03:00Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Il arrive qu&amp;#8217;on ait besoin d&amp;#8217;utiliser la sortie d&amp;#8217;une commande comme si c&amp;#8217;&#233;tait un fichier. Voici une petite astuce pour ne pas passer par un fichier temporaire.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;diff &lt;span class='bi'&gt;&amp;lt;&lt;/span&gt;(ls /un/dossier/au/pif) &lt;span class='bi'&gt;&amp;lt;&lt;/span&gt;(ls /un/autre/dossier/au/pif)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Et voil&#224; avec cette syntaxe on a la diff&#233;rence entre deux dossiers sans utiliser de fichiers temporaires.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Installer la gem mysql sous Snow Leopard</title>
    <link href="http://blog.happynoff.fr/post/Installer-la-gem-mysql-sous-Snow-Leopard" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Installer-la-gem-mysql-sous-Snow-Leopard</id>
    <updated>2011-08-25T15:03:00Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Sous &lt;em&gt;Snow Leopard&lt;/em&gt;, l&amp;#8217;installation de la gem mysql n&amp;#8217;est pas toujours simple. Voici ce que j&amp;#8217;utilise, sachant que mon &lt;em&gt;MySQL&lt;/em&gt; est install&#233; via le DMG fourni sur le site officiel.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='fu'&gt;export&lt;/span&gt; &lt;span class='iv'&gt;ARCHFLAGS&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;-arch i386 -arch x86_64&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='dl'&gt;;&lt;/span&gt;&lt;br&gt;sudo gem install mysql -v2.&lt;span class='i'&gt;7&lt;/span&gt; --no-rdoc --no-ri --         \&lt;br&gt;   --with-mysql-dir=/usr/&lt;span class='fu'&gt;local&lt;/span&gt;/mysql                      \&lt;br&gt;   --with-mysql-config=/usr/&lt;span class='fu'&gt;local&lt;/span&gt;/mysql/bin/mysql_config&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Probl&#232;me de police trop fine sous Snow Leopard</title>
    <link href="http://blog.happynoff.fr/post/Probleme-de-police-trop-fine-sous-Snow-Leopard" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Probleme-de-police-trop-fine-sous-Snow-Leopard</id>
    <updated>2011-08-25T15:02:59Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Il y a quelques jours j&amp;#8217;ai r&#233;install&#233; un Snow Leopard sur un Mac Mini.&lt;/p&gt;

&lt;p&gt;Lorsque j&amp;#8217;ai lanc&#233; iTerm et TextMate, la police Monaco que j&amp;#8217;utilise dans les deux n&amp;#8217;&#233;tait pas tout &#224; fait comme d&amp;#8217;habitude, plus fine et moins agr&#233;able.&lt;/p&gt;

&lt;p&gt;Cela vient d&amp;#8217;un bug Snow Leopard qui ne reconnait pas toujours les LCD : il les voit comme des &#233;crans CRT et d&#233;sactive l&amp;#8217;anti-aliasing sur les polices !&lt;/p&gt;

&lt;p&gt;Pour r&#233;gler ce souci, tapez simplement ceci dans une console :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;defaults -currentHost write -globalDomain AppleFontSmoothing -int &lt;span class='i'&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;La prochaine fois que vous lancerez iTerm ou TextMate, &#231;a devrait &#234;tre bon.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Pr&#233;sentation de TotalFinder</title>
    <link href="http://blog.happynoff.fr/post/Presentation-de-TotalFinder" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Presentation-de-TotalFinder</id>
    <updated>2011-08-25T15:02:59Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Je n&amp;#8217;ai pas pour habitude de faire la promotion de logiciels particuliers sur mon blog. Petite exception, je vais vous parler de &lt;a href='http://totalfinder.binaryage.com/'&gt;TotalFinder&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://totalfinder.binaryage.com/'&gt;TotalFinder&lt;/a&gt; est un plug-in pour &lt;em&gt;Finder&lt;/em&gt; qui donne acc&#232;s &#224; pas mal de fonctionnalit&#233;s bien pratiques.&lt;/p&gt;    </summary>
    <content type="html">
&lt;h2 id='r&#233;glages'&gt;R&#233;glages&lt;/h2&gt;

&lt;p&gt;Le param&#233;trage de &lt;a href='http://totalfinder.binaryage.com/'&gt;TotalFinder&lt;/a&gt; se fait gr&#226;ce &#224; une entr&#233;e sp&#233;cifique dans les pr&#233;f&#233;rences de &lt;em&gt;Finder&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/TotalFinder/pref-none.png' alt='Preferences TotalFinder' /&gt;&lt;/p&gt;

&lt;p&gt;Le panneau de configuration se divise en plusieurs sections regroupant les diff&#233;rentes fonctionnalit&#233;s que je vais d&#233;crire.&lt;/p&gt;

&lt;h2 id='les_onglets'&gt;Les onglets&lt;/h2&gt;

&lt;p&gt;Un des principaux apports de &lt;a href='http://totalfinder.binaryage.com/'&gt;TotalFinder&lt;/a&gt; est la pr&#233;sence d&amp;#8217;onglets dans les fen&#234;tres &lt;em&gt;Finder&lt;/em&gt;. Ils ressemblent comme deux gouttes d&amp;#8217;eau &#224; ceux du navigateur &lt;em&gt;Chrome&lt;/em&gt; de &lt;em&gt;Google&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/TotalFinder/tabs.png' alt='Onglets de TotalFinder' /&gt;&lt;/p&gt;

&lt;p&gt;Il est &#233;galement possible de grouper deux onglets pour obtenir une fen&#234;tre scind&#233;e en deux.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/TotalFinder/dual-mode.png' alt='Vue scindee' /&gt;&lt;/p&gt;

&lt;h2 id='visor'&gt;Visor&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Visor&lt;/em&gt; est une fen&#234;tre &lt;em&gt;Finder&lt;/em&gt; qui a pour particularit&#233; d&amp;#8217;&#234;tre toujours accessible gr&#226;ce &#224; un simple raccourci clavier.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/TotalFinder/visor-fade.png' alt='Fenetre Visor' /&gt;&lt;/p&gt;

&lt;p&gt;Le raccourci est, par d&#233;faut, option-`. Pour ceux qui, comme moi, utilisent un clavier &lt;em&gt;QWERTY&lt;/em&gt; mais &#233;crivent tout de m&#234;me avec les accents, ce raccourci n&amp;#8217;est pas des plus pratiques. Heureusement, cela se change facilement.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/TotalFinder/pref-visor.png' alt='Reglages Visor' /&gt;&lt;/p&gt;

&lt;p&gt;On peut voir que quelques options sont &#233;galement param&#233;trables.&lt;/p&gt;

&lt;h2 id='asepsis'&gt;Asepsis&lt;/h2&gt;

&lt;p&gt;Le but d&amp;#8217;_Asepsis_ est d&amp;#8217;&#233;viter la cr&#233;ation des .DS_Store dans les dossiers locaux.&lt;/p&gt;

&lt;p&gt;Ces fichiers servent &#224; stocker les options d&amp;#8217;affichage des dossiers mais peuvent devenir encombrants lorsque l&amp;#8217;on copie ces derniers sur un serveur ou une cl&#233; USB.&lt;/p&gt;

&lt;p&gt;Plut&#244;t que de prendre le parti d&amp;#8217;emp&#234;cher leur cr&#233;ation, &lt;a href='http://totalfinder.binaryage.com/'&gt;TotalFinder&lt;/a&gt; les centralise simplement dans un autre dossier (/usr/local/.dscache).&lt;/p&gt;

&lt;p&gt;De plus, une option permet d&amp;#8217;&#233;viter la cr&#233;ation de ces fichiers sur les machines distantes que l&amp;#8217;on visite.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/TotalFinder/pref-asepsis.png' alt='Reglages Asepsis' /&gt;&lt;/p&gt;

&lt;h2 id='tweaks'&gt;Tweaks&lt;/h2&gt;

&lt;p&gt;L&amp;#8217;onglet &lt;em&gt;Tweaks&lt;/em&gt; contient bon nombre d&amp;#8217;options bien utiles. Ces options sont d&amp;#8217;ailleurs ce qui m&amp;#8217;a amen&#233; &#224; utiliser &lt;a href='http://totalfinder.binaryage.com/'&gt;TotalFinder&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Quand on vient de &lt;em&gt;Linux&lt;/em&gt; ou m&#234;me, soyons fous, de &lt;em&gt;Windows&lt;/em&gt;, on est habitu&#233; &#224; quelques petites choses qui peuvent cruellement manquer lorsque l&amp;#8217;on passe sous &lt;em&gt;OS X&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Il faut &#234;tre honn&#234;te, &lt;em&gt;Finder&lt;/em&gt; n&amp;#8217;est pas le logiciel magique qui sauve des vies tous les jours&amp;#8230; Parmi les options qui manquent on trouvera :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;la possibilit&#233; d&amp;#8217;afficher les fichiers syst&#232;me ;&lt;/li&gt;

&lt;li&gt;le tri des dossiers au dessus des fichiers ;&lt;/li&gt;

&lt;li&gt;la maximisation de la fen&#234;tre.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TotalFinder est l&#224; pour nous offrir ce qui aurait d&#251; &#234;tre pr&#233;sent depuis toujours.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/TotalFinder/pref-tweaks.png' alt='Tweaks dans TotalFinder' /&gt;&lt;/p&gt;

&lt;h2 id='t&#233;l&#233;chargement'&gt;T&#233;l&#233;chargement&lt;/h2&gt;

&lt;p&gt;Une version d&amp;#8217;essai de 30 jours est disponible.&lt;/p&gt;

&lt;p&gt;Tout se passe sur &lt;a href='http://totalfinder.binaryage.com/'&gt;http://totalfinder.binaryage.com/&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='le_prix'&gt;Le prix&lt;/h2&gt;

&lt;p&gt;On l&amp;#8217;oublie parfois mais tous les logiciels ne sont pas gratuits. &lt;a href='http://totalfinder.binaryage.com/'&gt;TotalFinder&lt;/a&gt; est effectivement payant mais le prix est tout &#224; fait raisonnable. 15$ soit environ 10&#8364; ce qui est assez peu par rapport &#224; ce que l&amp;#8217;on peut d&#233;penser pour tant de choses bien moins utiles.&lt;/p&gt;

&lt;p&gt;Il existe toutefois des moyens d&amp;#8217;obtenir une licence gratuite. En participant au projet, en aidant &#224; d&#233;nicher des bugs ou en faisant la promotion de ce produit.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Travailler en case-sensitive sous Mac</title>
    <link href="http://blog.happynoff.fr/post/Travailler-en-case-sensitive-sous-Mac" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Travailler-en-case-sensitive-sous-Mac</id>
    <updated>2011-08-25T15:02:59Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;&lt;em&gt;HFS+&lt;/em&gt;, le syst&#232;me de fichiers utilis&#233; par &lt;em&gt;Mac OS X&lt;/em&gt; depuis un bout de temps d&#233;j&#224; est, par d&#233;faut, case-insensitive. Il est toutefois possible, aujourd&amp;#8217;hui, de choisir d&amp;#8217;utiliser une version case-sensitive lorsque l&amp;#8217;on installe &lt;em&gt;OS X&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;La plupart du temps, &#231;a n&amp;#8217;est pas sp&#233;cialement g&#234;nant. Quand il s&amp;#8217;agit de travailler cela peut vite devenir handicapant.&lt;/p&gt;    </summary>
    <content type="html">
&lt;p&gt;Exemple simple, travailler avec un &lt;abbr title='Source Control Manager'&gt;SCM&lt;/abbr&gt; comme &lt;em&gt;Git&lt;/em&gt; ou &lt;em&gt;Subversion&lt;/em&gt;. Un utilisateur utilisant un syst&#232;me case-sensitive ajoutera sans probl&#232;me deux fichiers nomm&#233;s &lt;em&gt;Hello.txt&lt;/em&gt; et &lt;em&gt;hello.txt&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Si on met &#224; jour notre copie de travail, on se retrouve avec un seul fichier mais l&amp;#8217;outil de versionning qui en suit deux en vois toujours un modifi&#233;.&lt;/p&gt;
&lt;pre class='shell'&gt;&lt;kbd&gt;svn st&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;M hello.txt&lt;/samp&gt;&lt;br&gt;&lt;br&gt;&lt;kbd&gt;svn revert hello.txt&lt;/kbd&gt;&lt;br&gt;&lt;kbd&gt;svn st&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;M Hello.txt&lt;/samp&gt;&lt;br&gt;&lt;/pre&gt;
&lt;h2 id='solutions'&gt;Solutions&lt;/h2&gt;

&lt;p&gt;&#192; ce stade, peu de solutions s&amp;#8217;offrent &#224; nous, la premi&#232;re &#233;tant de r&#233;installer &lt;em&gt;OS X&lt;/em&gt; et de choisir d&amp;#8217;utiliser &lt;em&gt;HFS+&lt;/em&gt; en case-sensitive.&lt;/p&gt;

&lt;p&gt;&#201;tant donn&#233; que ce n&amp;#8217;est pas la plus pratique des options, une alternative serait la bienvenue.&lt;/p&gt;

&lt;p&gt;En voici une.&lt;/p&gt;

&lt;h3 id='cr&#233;er_un_volume_dmg'&gt;Cr&#233;er un volume &lt;abbr title='Apple Disk Image'&gt;DMG&lt;/abbr&gt;&lt;/h3&gt;

&lt;p&gt;Cela revient &#224; cr&#233;er un volume amovible qui peut &#234;tre utilis&#233; comme une cl&#233; USB ou un disque dur externe. Un &lt;abbr title='Apple Disk Image'&gt;DMG&lt;/abbr&gt; peut donc &#234;tre partitionn&#233;. Il est alors possible de formater une partition en &lt;em&gt;HFS+&lt;/em&gt; case-sensitive &#224; l&amp;#8217;int&#233;rieur de ce dernier.&lt;/p&gt;

&lt;p&gt;L&amp;#8217;outil Disk Utility (pr&#233;sent de base sur &lt;em&gt;OS X&lt;/em&gt;) permet de cr&#233;er des &lt;abbr title='Apple Disk Image'&gt;DMG&lt;/abbr&gt;. Il suffit de le lancer, de cliquer sur Nouvelle Image.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/disk_util_new_image.png' alt='disk utility new image' /&gt;&lt;/p&gt;

&lt;p&gt;R&#233;glons ensuite les param&#232;tres en fonction de nos besoins :&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/disk_util_settings.png' alt='disk utility' /&gt;&lt;/p&gt;

&lt;p&gt;Une fois le &lt;abbr title='Apple Disk Image'&gt;DMG&lt;/abbr&gt; cr&#233;&#233;, il ne reste plus qu&amp;#8217;&#224; le monter comme n&amp;#8217;importe quel &lt;abbr title='Apple Disk Image'&gt;DMG&lt;/abbr&gt; et de copier le contenu de la copie de travail dedans.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ATTENTION !&lt;/strong&gt; N&amp;#8217;oubliez pas les &lt;em&gt;.git&lt;/em&gt; ou &lt;em&gt;.svn&lt;/em&gt; sinon &#231;a ne fonctionnera pas !&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>D&#233;sactiver la r&#233;solution interactive des conflits dans Subversion</title>
    <link href="http://blog.happynoff.fr/post/Desactiver-la-resolution-interactive-des-conflits-dans-Subversion" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Desactiver-la-resolution-interactive-des-conflits-dans-Subversion</id>
    <updated>2011-08-25T15:02:59Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Depuis la version 1.5 de Subversion, la r&#233;solution des conflits se fait de fa&#231;on interactive lorsque l&amp;#8217;on utilise &lt;em&gt;svn update&lt;/em&gt;.&lt;/p&gt;
&lt;pre class='shell'&gt;&lt;kbd&gt;svn update&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;Conflict discovered in 'some/file/located/somewhere.rb'.&lt;/samp&gt;&lt;br&gt;&lt;samp&gt;Select: (p) postpone, (df) diff-full, (e) edit,&lt;br&gt;        (h) help for more options:&lt;/samp&gt;&lt;br&gt;&lt;/pre&gt;
&lt;p&gt;Personnellement, je ne supporte pas ce nouveau mode. Je pr&#233;f&#232;re de loin faire un &lt;em&gt;update&lt;/em&gt; complet et corriger les conflits &#224; posteriori.&lt;/p&gt;

&lt;p&gt;Pour le faire de mani&#232;re ponctuelle l&amp;#8217;option &lt;em&gt;&amp;#8211;non-interactive&lt;/em&gt; permet d&amp;#8217;obtenir ce comportement.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;svn update --non-interactive&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pour le faire de mani&#232;re permanente, &#233;ditez votre &lt;em&gt;~/.subversion/config&lt;/em&gt; et ajoutez la ligne suivante dans la section &lt;em&gt;miscellany&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;[miscellany]&lt;br&gt;...&lt;br&gt;interactive-conflicts = no&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Surcharge de m&#233;thode &#233;l&#233;gante en Javascript</title>
    <link href="http://blog.happynoff.fr/post/Surcharge-de-methode-elegante-en-Javascript" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Surcharge-de-methode-elegante-en-Javascript</id>
    <updated>2011-08-25T15:02:52Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Aujourd&amp;#8217;hui, j&amp;#8217;ai eu besoin de surcharger une m&#233;thode Javascript. Premier r&#233;flexe, r&#233;&#233;crire la fonction en y ajoutant le code voulu.&lt;/p&gt;

&lt;p&gt;Soit le code qui suit :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;mon_objet.fait_le_caf&lt;span class='er'&gt;&#233;&lt;/span&gt; = &lt;span class='kw'&gt;function&lt;/span&gt;() {&lt;br&gt;  &lt;span class='kw'&gt;var&lt;/span&gt; tasse = prendre_une_tasse();&lt;br&gt;  tasse.verser_caf&lt;span class='er'&gt;&#233;&lt;/span&gt;();&lt;br&gt;  tasse.faire_chauffer();&lt;br&gt;&lt;br&gt;  &lt;span class='kw'&gt;return&lt;/span&gt; tasse;&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Afin d&amp;#8217;ajouter du sucre, on pourrait surcharger de la fa&#231;on suivante :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;mon_objet.fait_le_caf&lt;span class='er'&gt;&#233;&lt;/span&gt; = &lt;span class='kw'&gt;function&lt;/span&gt;() {&lt;br&gt;  &lt;span class='kw'&gt;var&lt;/span&gt; tasse = prendre_une_tasse();&lt;br&gt;  tasse.verser_caf&lt;span class='er'&gt;&#233;&lt;/span&gt;();&lt;br&gt;  tasse.faire_chauffer();&lt;br&gt;&lt;br&gt;  tasse.ajouter_sucre();&lt;br&gt;&lt;br&gt;  &lt;span class='kw'&gt;return&lt;/span&gt; tasse;&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Jusque l&#224;, rien d&amp;#8217;inhabituel. Mais quid du code propre, simple et surtout &lt;abbr title='Don&amp;apos;t Repeat Yourself'&gt;DRY&lt;/abbr&gt; ?&lt;/p&gt;

&lt;p&gt;Voici donc une fa&#231;on plus &#233;l&#233;gante d&amp;#8217;obtenir le m&#234;me r&#233;sultat en &#233;crivant juste le code n&#233;cessaire :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;mon_objet.fait_le_caf&lt;span class='er'&gt;&#233;&lt;/span&gt;_sans_sucre = mon_objet.fait_le_caf&lt;span class='er'&gt;&#233;&lt;/span&gt;;&lt;br&gt;&lt;br&gt;mon_objet.fait_le_caf&lt;span class='er'&gt;&#233;&lt;/span&gt; = &lt;span class='kw'&gt;function&lt;/span&gt;() {&lt;br&gt;  &lt;span class='kw'&gt;var&lt;/span&gt; tasse = mon_objet.fait_le_caf&lt;span class='er'&gt;&#233;&lt;/span&gt;_sans_sucre();&lt;br&gt;&lt;br&gt;  tasse.ajouter_sucre();&lt;br&gt;&lt;br&gt;  &lt;span class='kw'&gt;return&lt;/span&gt; tasse;&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;C&amp;#8217;est tout simple, &#231;a fonctionne et c&amp;#8217;est &lt;abbr title='Don&amp;apos;t Repeat Yourself'&gt;DRY&lt;/abbr&gt;&amp;#8230;&lt;/p&gt;

&lt;p&gt;Pour information, l&amp;#8217;id&#233;e m&amp;#8217;est venue du framework &lt;a href='http://www.rubyonrails.org'&gt;Ruby On Rails (en)&lt;/a&gt; et de sa m&#233;thode&lt;/p&gt;

&lt;p&gt;&lt;a href='http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Module.html#M001219'&gt;alias_method_chain (en)&lt;/a&gt;&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Rails - Utiliser SASS avec theme_support</title>
    <link href="http://blog.happynoff.fr/post/Rails-Utiliser-SASS-avec-theme_support" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Rails-Utiliser-SASS-avec-theme_support</id>
    <updated>2011-08-25T15:02:58Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;J&amp;#8217;ai eu l&amp;#8217;occasion de me prendre un petit moment la t&#234;te aujourd&amp;#8217;hui sur comment utiliser des feuilles de styles SASS au sein de th&#232;mes dans une application Rails.&lt;/p&gt;

&lt;p&gt;Pour la gestion des th&#232;mes, j&amp;#8217;ai utilis&#233; theme_support qui permet de cr&#233;er, pour chaque th&#232;me, un dossier ayant l&amp;#8217;arborescence suivante :&lt;/p&gt;
&lt;pre&gt;un_theme&lt;br&gt;&lt;span class='deco'&gt;&#9500;&#9472;&#9472;&lt;/span&gt; images&lt;br&gt;&lt;span class='deco'&gt;|   &#9492;&#9472;&#9472;&lt;/span&gt; preview.png&lt;br&gt;&lt;span class='deco'&gt;&#9500;&#9472;&#9472;&lt;/span&gt; javascripts&lt;br&gt;&lt;span class='deco'&gt;&#9500;&#9472;&#9472;&lt;/span&gt; stylesheets&lt;br&gt;&lt;span class='deco'&gt;&#9500;&#9472;&#9472;&lt;/span&gt; views&lt;br&gt;&lt;span class='deco'&gt;&#9492;&#9472;&#9472;&lt;/span&gt; about.markdown&lt;/pre&gt;
&lt;p&gt;Ce que je cherchais &#224; faire &#233;tait de pouvoir mettre des fichiers SASS dans le dossier stylesheets, mais que les CSS compil&#233;es soient plac&#233;es dans &lt;em&gt;&amp;lt;app_root&amp;gt;/public/stylesheets&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Le plus simple moyen que j&amp;#8217;ai trouv&#233; pour faire &#231;a, est d&amp;#8217;ajouter le script suivant dans &amp;gt;app_root&amp;gt;/config/initializers/theme_sass.rb :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='c'&gt;# :template_location est normalement une String, on la convertie donc en Array&lt;/span&gt;&lt;br&gt;&lt;span class='co'&gt;Sass&lt;/span&gt;::&lt;span class='co'&gt;Plugin&lt;/span&gt;.options[&lt;span class='sy'&gt;:template_location&lt;/span&gt;] = [[&lt;span class='co'&gt;Sass&lt;/span&gt;::&lt;span class='co'&gt;Plugin&lt;/span&gt;.options[&lt;span class='sy'&gt;:template_location&lt;/span&gt;], &lt;span class='co'&gt;Sass&lt;/span&gt;::&lt;span class='co'&gt;Plugin&lt;/span&gt;.options[&lt;span class='sy'&gt;:css_location&lt;/span&gt;]]]&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;# Pour chaque th&#232;me, on ajoute son dossier stylesheets &#224; la liste des sources SASS&lt;/span&gt;&lt;br&gt;&lt;span class='co'&gt;Theme&lt;/span&gt;.find_all.map(&amp;amp;&lt;span class='sy'&gt;:name&lt;/span&gt;).each &lt;span class='r'&gt;do&lt;/span&gt; |theme|&lt;br&gt;  &lt;span class='co'&gt;Sass&lt;/span&gt;::&lt;span class='co'&gt;Plugin&lt;/span&gt;.options[&lt;span class='sy'&gt;:template_location&lt;/span&gt;] &amp;lt;&amp;lt; [&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='il'&gt;&lt;span class='idl'&gt;#{&lt;/span&gt;&lt;span class='co'&gt;RAILS_ROOT&lt;/span&gt;&lt;span class='idl'&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class='k'&gt;/themes/&lt;/span&gt;&lt;span class='il'&gt;&lt;span class='idl'&gt;#{&lt;/span&gt;theme&lt;span class='idl'&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class='k'&gt;/stylesheets&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class='co'&gt;Sass&lt;/span&gt;::&lt;span class='co'&gt;Plugin&lt;/span&gt;.options[&lt;span class='sy'&gt;:css_location&lt;/span&gt;]]&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Continuer d'ouvrir ses onglets en fin de liste sous Firefox 3.6</title>
    <link href="http://blog.happynoff.fr/post/Continuer-d-ouvrir-ses-onglets-en-fin-de-liste-sous-Firefox-3-6" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Continuer-d-ouvrir-ses-onglets-en-fin-de-liste-sous-Firefox-3-6</id>
    <updated>2011-08-25T15:02:56Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Depuis quelques jours maintenant, Firefox 3.6 est sorti. Cette nouvelle version apporte un certain nombre de nouveaut&#233;s, dont certaines qui peuvent &#234;tre d&#233;routantes (&amp;#60;troll&amp;#62;le nouveau syst&#232;me de skins uselessfull par exemple ?&amp;#60;/troll&amp;#62;).&lt;/p&gt;

&lt;p&gt;Bref ! Une nouveaut&#233; est l&amp;#8217;ouverture des onglets relatifs (ouverture d&amp;#8217;un lien de la page courante dans un onglet) &#224; c&#244;t&#233; de l&amp;#8217;onglet courant et non plus &#224; la fin de la liste. Tout cela n&amp;#8217;aurait rien de bien g&#234;nant si cette fonctionnalit&#233; pouvait &#234;tre d&#233;sactiv&#233;e gr&#226;ce &#224; une simple case &#224; cocher&amp;#8230;&lt;/p&gt;

&lt;p&gt;Voici un moyen simple de revenir &#224; l&amp;#8217;ancien fonctionnement.&lt;/p&gt;

&lt;p&gt;Ouvrez l&amp;#8217;URL &lt;em&gt;about:config&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Dans la zone de filtre saisissez &lt;em&gt;insertRelated&lt;/em&gt; cela devrait laisser seulement une entr&#233;e :&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/ff3.6_aboutconfig_tabs.png' alt='Firefox 3.6 about:config - insertRelatedTabsAfterCurrent' /&gt;&lt;/p&gt;

&lt;p&gt;Double-cliquez dessus pour passer sa valeur &#224; &lt;em&gt;false&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;C&amp;#8217;est tout. Les nouveaux onglets devraient s&amp;#8217;ouvrir maintenant en fin de liste.&lt;/p&gt;

&lt;p&gt;EDIT: Je viens de trouver &lt;a href='http://mozillalinks.org/wp/2010/01/firefox-3-6-tips-and-tweaks/'&gt;un lien avec quelques astuces suppl&#233;mentaires&lt;/a&gt;&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Utiliser GetText c&#244;t&#233; Javascript avec Rails</title>
    <link href="http://blog.happynoff.fr/post/Utiliser-GetText-cote-Javascript-avec-Rails" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Utiliser-GetText-cote-Javascript-avec-Rails</id>
    <updated>2011-08-25T15:02:56Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;En travaillant sur une petite application Rails, j&amp;#8217;ai utilis&#233; GetText pour l&amp;#8217;internationalisation. Jusque l&#224;, pas de probl&#232;me&amp;#8230; Sauf au moment o&#249; j&amp;#8217;ai voulu traduire un message c&#244;t&#233; client (autrement dit Javascript).&lt;/p&gt;

&lt;p&gt;Je ne voulais pas faire d&amp;#8217;appel AJAX pour chaque chaine &#224; traduire.&lt;/p&gt;

&lt;p&gt;Tout naturellement, j&amp;#8217;ai cherch&#233; un plugin simple qui fasse le travail mais n&amp;#8217;ai rien trouv&#233; qui me convienne.&lt;/p&gt;

&lt;p&gt;J&amp;#8217;ai donc cr&#233;&#233; mon propre plugin, &lt;a href='http://github.com/simonc/gettext_json'&gt;gettext_json&lt;/a&gt;. Voici comment l&amp;#8217;utiliser.&lt;/p&gt;    </summary>
    <content type="html">
&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;gettext_json s&amp;#8217;installe comme n&amp;#8217;importe quel plugin Rails. Donc, au choix :&lt;/p&gt;

&lt;p&gt;La m&#233;thode par gem :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;gem install gettext_json&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Dans &lt;em&gt;config/environment.rb&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;config.gem &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;gettext_json&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class='sy'&gt;:version&lt;/span&gt; =&amp;gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;&amp;gt;= 0.0.2&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Puis, &#224; la racine de votre application :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;rake gems&lt;span class='r'&gt;:&lt;/span&gt;install&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Le m&#233;thode &lt;em&gt;vendor/plugins&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;./script/plugin install git&lt;span class='r'&gt;:&lt;/span&gt;//github.com/simonc/gettext_json.git&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='utilisation'&gt;Utilisation&lt;/h2&gt;

&lt;h3 id='initialisation'&gt;Initialisation&lt;/h3&gt;

&lt;p&gt;La premi&#232;re &#233;tape est de faire appel au g&#233;n&#233;rateur gettext_json :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;./script/generate gettext_json&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Ceci va cr&#233;er trois fichiers :&lt;/p&gt;

&lt;dl&gt;
&lt;dt&gt;gettext_json.js&lt;/dt&gt;

&lt;dd&gt;La micro librairie Javascript.&lt;/dd&gt;

&lt;dt&gt;lib/js_parser.rb&lt;/dt&gt;

&lt;dd&gt;Le parser de fichiers javascript pour GetText.&lt;/dd&gt;

&lt;dt&gt;lib/tasks/gettext_json.rake&lt;/dt&gt;

&lt;dd&gt;Contient la t&#226;che rake makemo:json&lt;/dd&gt;
&lt;/dl&gt;

&lt;h3 id='g&#233;n&#233;ration_des_traductions'&gt;G&#233;n&#233;ration des traductions&lt;/h3&gt;

&lt;p&gt;Lorsque l&amp;#8217;on utilise GetText avec Rails, on se sert en g&#233;n&#233;ral de deux t&#226;ches rake : &lt;em&gt;updatepo&lt;/em&gt; et &lt;em&gt;makemo&lt;/em&gt;. Pour plus d&amp;#8217;informations : &lt;a href='http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html#Rakefile'&gt;Ruby-gettext-howto-rails&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Pour que les chaines &#224; traduire dans les fichiers Javascript soient prises en compte, votre t&#226;che updatepo doit ressembler &#224; ceci :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;desc &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;Update pot/po files.&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;task &lt;span class='sy'&gt;:updatepo&lt;/span&gt; &lt;span class='r'&gt;do&lt;/span&gt;&lt;br&gt;  require &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;gettext_rails/tools&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  require &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;js_parser&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='co'&gt;GetText&lt;/span&gt;.update_pofiles(&lt;br&gt;    &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;your_app&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,&lt;br&gt;    &lt;span class='co'&gt;Dir&lt;/span&gt;.glob(&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;{app,lib,bin,public}/**/*.{rb,erb,rjs,js}&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;),&lt;br&gt;    &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;your_app 1.0.0&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  )&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Il ne reste plus qu&amp;#8217;&#224; faire appel &#224; la t&#226;che rake pour obtenir les nouvelles chaines :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;rake updatepo&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id='g&#233;n&#233;ration_du_fichier_json'&gt;G&#233;n&#233;ration du fichier JSON&lt;/h3&gt;

&lt;p&gt;Pour g&#233;n&#233;rer le fichier de traductions utilisables par Javascript, utilisez la t&#226;che rake suivante :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;rake makemo&lt;span class='r'&gt;:&lt;/span&gt;json&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Un fichier &lt;em&gt;public/javascripts/gettext_json_translations.js&lt;/em&gt; va &#234;tre cr&#233;&#233;.&lt;/p&gt;

&lt;h3 id='traduction_des_chaines'&gt;Traduction des chaines&lt;/h3&gt;

&lt;p&gt;Pour utiliser GetText c&#244;t&#233; Javascript, il faut inclure deux fichiers dans le layout de l&amp;#8217;application :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='il'&gt;&lt;span class='idl'&gt;&amp;lt;%=&lt;/span&gt; javascript_include_tag &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;gettext_json.js&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='idl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class='il'&gt;&lt;span class='idl'&gt;&amp;lt;%=&lt;/span&gt; javascript_include_tag &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;gettext_json_translations.js&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class='idl'&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Il vous suffit ensuite dans vos scripts d&amp;#8217;utiliser la micro librairie :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='c'&gt;// D&#233;finir la locale courante (la valeur par d&#233;faut est 'en')&lt;/span&gt;&lt;br&gt;GetText.locale = &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;fr&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;&lt;br&gt;&lt;span class='kw'&gt;var&lt;/span&gt; str = GetText.t(&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;Hello World&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;br&gt;&lt;span class='c'&gt;//=&amp;gt; &amp;quot;Bonjour le Monde&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='en_savoir_plus'&gt;En savoir plus&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://github.com/simonc/gettext_json'&gt;gettext_json sur Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;    </content>
  </entry>
  <entry>
    <title>Mettre en place un groupe de sites de d&#233;monstration</title>
    <link href="http://blog.happynoff.fr/post/Mettre-en-place-un-groupe-de-sites-de-demonstration" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Mettre-en-place-un-groupe-de-sites-de-demonstration</id>
    <updated>2011-08-25T15:02:55Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Quand on d&#233;veloppe de nombreux sites, on n&amp;#8217;a pas forcement envie de toucher &#224; ses VirtualHosts pour chaque nouveau site.&lt;/p&gt;

&lt;p&gt;Voici ce que j&amp;#8217;ai mis en place sur mon serveur pour l&amp;#8217;espace de d&#233;mo de ce genre de sites.&lt;/p&gt;

&lt;p&gt;Le but &#233;tait d&amp;#8217;avoir un dossier contenant un nombre non limit&#233; de dossiers nomm&#233;s demo1, demo2, demo3, etc&amp;#8230;&lt;/p&gt;

&lt;p&gt;Pour cela, j&amp;#8217;ai cr&#233;&#233; un dossier &lt;em&gt;demos&lt;/em&gt; &#224; la racine de mon serveur Apache. C&amp;#8217;est ce dossier qui va contenir tous les dossiers &lt;em&gt;demoXYZ&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;J&amp;#8217;ai ensuite ajout&#233; un VirtualHost comme ceci :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;br&gt;  ServerName demos.exemple.com&lt;br&gt;  ServerAlias demo*.exemple.com&lt;br&gt;  DocumentRoot /var/www/demos&lt;br&gt;&lt;br&gt;  &amp;lt;Directory /&amp;gt;&lt;br&gt;    AllowOverride all&lt;br&gt;  &amp;lt;/Directory&amp;gt;&lt;br&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Le travail de dispatch entre les diff&#233;rents dossiers de d&#233;mo est fait par un fichier .htaccess dans le dossier demos :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;RewriteEngine On&lt;br&gt;RewriteCond %{HTTP_HOST} ^demo(\d+).exemple.com&lt;br&gt;RewriteCond %{REQUEST_URI} !^/demo&lt;br&gt;RewriteRule (.\*) demo%1/$1 [L]&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Et voil&#224; ! Apr&#232;s red&#233;marrage du serveur, tout devrait fonctionner.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Deverouiller un groupe de fichiers sous Mac</title>
    <link href="http://blog.happynoff.fr/post/Deverouiller-un-groupe-de-fichiers-sous-Mac" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Deverouiller-un-groupe-de-fichiers-sous-Mac</id>
    <updated>2011-08-25T15:02:58Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Derni&#232;rement, lors de la copie de fichiers depuis le disque dur d&amp;#8217;une amie, je me suis retrouv&#233; avec de nombreux fichiers verrouill&#233;s. Verrouill&#233;s au sens OS X du terme.&lt;/p&gt;

&lt;p&gt;Il est possible pour chaque fichier d&amp;#8217;afficher ses infos et de d&#233;cocher la case de verrouillage.&lt;/p&gt;

&lt;p&gt;Mais lorsque cela concerne une centaine, ou un millier de fichiers, d&amp;#8217;un coup, cocher une simple case peut devenir quelque peu fastidieux.&lt;/p&gt;

&lt;p&gt;Pour effectuer cette action en ligne de commande, il suffit d&amp;#8217;utiliser la ligne suivante :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;chflags nouchg &lt;span class='bi'&gt;&amp;lt;&lt;/span&gt;fichiers&lt;span class='bi'&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Utiliser Paperclip avec Rails sous Mac</title>
    <link href="http://blog.happynoff.fr/post/Utiliser-Paperclip-avec-Rails-sous-Mac" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Utiliser-Paperclip-avec-Rails-sous-Mac</id>
    <updated>2011-08-25T15:02:58Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Pour g&#233;rer l&amp;#8217;upload de fichiers dans les applications Rails, un plugin fr&#233;quemment utilis&#233; est Paperclip. R&#233;cemment, lors du d&#233;veloppement d&amp;#8217;un projet, je me suis retrouv&#233; confront&#233; &#224; un probl&#232;me lors de l&amp;#8217;envoie des fichiers. En effet, &#231;a ne fonctionnait pas et je recevais un message d&amp;#8217;erreur &#224; chaque fois.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/erreur_paperclip.jpg' alt='Erreur Paperclip' /&gt;&lt;/p&gt;

&lt;p&gt;Apr&#232;s quelques recherches, j&amp;#8217;ai fini par trouver que cette erreur venait du fait que mon application ne trouvait pas son chemin vers les outils d&amp;#8217;ImageMagick dont Paperclip d&#233;pend au travers de Rmagick.&lt;/p&gt;

&lt;p&gt;Pour r&#233;soudre ce probl&#232;me, il suffit d&amp;#8217;ajouter un initialiseur &#224; l&amp;#8217;application.&lt;/p&gt;

&lt;p&gt;J&amp;#8217;ai donc ajout&#233; le fichier RAILS_ROOT/config/initializers/paperclip.rb contenant ceci :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='co'&gt;Paperclip&lt;/span&gt;.options[&lt;span class='sy'&gt;:command_path&lt;/span&gt;] = &lt;span class='s'&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;span class='k'&gt;/opt/local/bin&lt;/span&gt;&lt;span class='dl'&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;J&amp;#8217;ai utilis&#233; ce chemin car j&amp;#8217;ai install&#233; ImageMagick en utilisant MacPorts.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>SSH automatique sur une machine au travers d'une autre</title>
    <link href="http://blog.happynoff.fr/post/SSH-automatique-sur-une-machine-au-travers-d-une-autre" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/SSH-automatique-sur-une-machine-au-travers-d-une-autre</id>
    <updated>2011-08-25T15:02:54Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Parfois, pour se connecter en SSH sur une machine, il est n&#233;cessaire de passer au pr&#233;alable par une passerelle.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/ssh_connection_through.png' alt='Connexion au travers dune autre machine' /&gt;&lt;/p&gt;

&lt;p&gt;Cela implique, en g&#233;n&#233;ral, le processus suivant :&lt;/p&gt;

&lt;p&gt;&lt;pre class='shell'&gt;&lt;samp class='prompt'&gt;$ &lt;/samp&gt;&lt;kbd&gt;ssh user1@machine1&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;Welcome to machine1 &lt;/samp&gt;&lt;br&gt;&lt;samp class='prompt'&gt;machine1&amp;gt; &lt;/samp&gt;&lt;kbd&gt;ssh user2@machine2&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;Welcome to machine2&lt;/samp&gt;&lt;br&gt;&lt;samp class='prompt'&gt;machine2&amp;gt; &lt;/samp&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Cela peut &#234;tre simplifi&#233; de plusieurs mani&#232;res.&lt;/p&gt;    </summary>
    <content type="html">
&lt;p&gt;Pour une connexion ponctuelle, l&amp;#8217;utilisation de l&amp;#8217;option &lt;em&gt;-t&lt;/em&gt; permet de gagner du temps :&lt;/p&gt;

&lt;p&gt;&lt;pre class='shell'&gt;&lt;samp class='prompt'&gt;$ &lt;/samp&gt;&lt;kbd&gt;ssh user1@machine1 -t user2@machine2&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;Welcome to machine1&lt;/samp&gt;&lt;br&gt;&lt;samp&gt;Welcome to machine2&lt;/samp&gt;&lt;br&gt;&lt;samp class='prompt'&gt;machine&amp;gt; &lt;/samp&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Quand il s&amp;#8217;agit d&amp;#8217;utiliser ce genre de connexion de fa&#231;on plus fr&#233;quente, d&#233;clarer ce m&#233;canisme en configuration est beaucoup plus simple. Pour ce faire, il suffit d&amp;#8217;&#233;diter le fichier &lt;em&gt;~/.ssh/config&lt;/em&gt; et d&amp;#8217;y ins&#233;rer les lignes suivantes :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;Host machine1&lt;br&gt;  User user1&lt;br&gt;&lt;br&gt;Host machine2&lt;br&gt;  User user2&lt;br&gt;  ProxyCommand ssh machine1 nc %h %p 2&amp;gt; /dev/null&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Cela permet de d&#233;finir la mani&#232;re dont on se connecte &#224; &lt;em&gt;machine2&lt;/em&gt; :&lt;/p&gt;
&lt;pre class='shell'&gt;&lt;samp class='prompt'&gt;$ &lt;/samp&gt;&lt;kbd&gt;ssh machine2&lt;/kbd&gt;&lt;br&gt;&lt;samp class='prompt'&gt;machine2&amp;gt; &lt;/samp&gt;&lt;/pre&gt;    </content>
  </entry>
  <entry>
    <title>Ignorer les changements d'espaces dans un diff SVN</title>
    <link href="http://blog.happynoff.fr/post/Ignorer-les-changements-d-espaces-dans-un-diff-SVN" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Ignorer-les-changements-d-espaces-dans-un-diff-SVN</id>
    <updated>2011-08-25T15:02:54Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Lorsque l&amp;#8217;on &#233;dite un fichier, il peut arriver qu&amp;#8217;en plus de simples modifications, certaines portions, voire le fichier entier, soient re-indent&#233;es. Malheureusement, Subversion &#233;tant b&#234;te et disciplin&#233;, un &lt;em&gt;svn diff&lt;/em&gt; montrera les lignes modifi&#233;es mais &#233;galement les lignes simplement indent&#233;es.&lt;/p&gt;

&lt;p&gt;Cela peut devenir g&#234;nant lorsque, par exemple, tout le fichier s&amp;#8217;en retrouve chang&#233;.&lt;/p&gt;

&lt;p&gt;Pour ignorer ces diff&#233;rences d&amp;#8217;espaces lors d&amp;#8217;un &lt;em&gt;diff&lt;/em&gt;, la commande &#224; utiliser est la suivante :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;svn diff --extensions -bu&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Probl&#232;me des noms de fichiers avec accents dans Subversion sous OS X</title>
    <link href="http://blog.happynoff.fr/post/Probleme-des-noms-de-fichiers-avec-accents-dans-Subversion-sous-OS-X" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Probleme-des-noms-de-fichiers-avec-accents-dans-Subversion-sous-OS-X</id>
    <updated>2011-08-25T15:02:54Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Si vous utilisez des fichiers dont le nom contient des accents sur un d&#233;p&#244;t &lt;abbr title='Subversion'&gt;SVN&lt;/abbr&gt;, vous avez de grandes chances de rencontrer quelques soucis sous Mac, si vous avez install&#233; Subversion avec &lt;em&gt;MacPorts&lt;/em&gt;. Le probl&#232;me vient de la diff&#233;rence de stockage des caract&#232;res unicode entre les plateformes &lt;em&gt;Unix&lt;/em&gt; et &lt;em&gt;OS X&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Voici comment r&#233;soudre ce probl&#232;me. C&amp;#8217;est tr&#232;s simple, il suffit d&amp;#8217;installer une variante du &lt;em&gt;port&lt;/em&gt; subversion.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;port install subversion +unicode_path&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Si tout s&amp;#8217;est bien pass&#233;, vous ne devriez plus avoir de probl&#232;mes.&lt;/p&gt;

&lt;p&gt;NOTE: j&amp;#8217;ai ajout&#233; cette option dans la Formula subversion de Homebrew mais c&amp;#8217;est toujours en attente de merge de leur part&amp;#8230;&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Utiliser TextMate pour les messages de commit SVN ou Git</title>
    <link href="http://blog.happynoff.fr/post/Utiliser-TextMate-pour-les-messages-de-commit-SVN-ou-Git" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Utiliser-TextMate-pour-les-messages-de-commit-SVN-ou-Git</id>
    <updated>2011-08-25T15:02:58Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Lorsque l&amp;#8217;on utilise un &#233;diteur de texte particulier, on appr&#233;cie de pouvoir l&amp;#8217;utiliser comme &#233;diteur par d&#233;faut pour peu tout. Cela comprend &#233;galement les messages de commit des outils tels que SVN ou Git.&lt;/p&gt;

&lt;p&gt;Malheureusement, utiliser un &#233;diteur graphique pour cela n&amp;#8217;est pas toujours trivial.&lt;/p&gt;

&lt;p&gt;La commande &lt;em&gt;mate&lt;/em&gt; propose l&amp;#8217;option &lt;em&gt;-w&lt;/em&gt; qui permet de signifier que l&amp;#8217;on veut attendre que TextMate en ait fini avec le fichier pour reprendre la main.&lt;/p&gt;
&lt;p class='note'&gt;Il est vrai que TextMate int&#232;gre les fonctionnalit&#233;s SVN et Git.
  Personnellement j'ai toujours pr&#233;f&#233;r&#233; m'occuper de ces choses l&#224; en ligne de
  commande... chacun son truc...&lt;/p&gt;
&lt;h2 id='pour_svn'&gt;Pour SVN&lt;/h2&gt;

&lt;p&gt;Il y a plusieurs fa&#231;ons de dire &#224; subversion d&amp;#8217;utiliser tel ou tel &#233;diteur, le plus simple est de donner une valeur &#224; la variable &lt;em&gt;SVN_EDITOR&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='fu'&gt;export&lt;/span&gt; &lt;span class='iv'&gt;SVN_EDITOR&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;mate -w&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='pour_git'&gt;Pour Git&lt;/h2&gt;

&lt;p&gt;Pour rester dans l&amp;#8217;utilisation habituelle de Git, on utilisera la commande suivante :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;git config --global core.editor &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;mate -w&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Relever automatiquement les mails des sous dossiers dans Thunderbird</title>
    <link href="http://blog.happynoff.fr/post/Relever-automatiquement-les-mails-des-sous-dossiers-dans-Thunderbird" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Relever-automatiquement-les-mails-des-sous-dossiers-dans-Thunderbird</id>
    <updated>2011-08-25T15:02:59Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Depuis plusieurs ann&#233;es maintenant, j&amp;#8217;utilise pour lire mes mails le logiciel Thunderbird. Pratique et efficace, il n&amp;#8217;en est pas moins dot&#233; de certains d&#233;fauts plus que g&#234;nants&amp;#8230;&lt;/p&gt;

&lt;p&gt;L&amp;#8217;un d&amp;#8217;eux est que Thunderbird ne rel&#232;ve pas automatiquement les mails dans les sous dossiers. Cela devient tr&#232;s g&#234;nant lorsque l&amp;#8217;on utilise un filtrage des messages &#224; la source, autrement dit, c&#244;t&#233; serveur.&lt;/p&gt;

&lt;p&gt;Il existe toutefois une solution. Il est possible de pr&#233;ciser, pour chaque dossier, que l&amp;#8217;on souhaite que Thunderbird v&#233;rifie les nouveaux messages.&lt;/p&gt;

&lt;p&gt;Pour ce faire, il suffit de faire un clic droit sur un dossier puis sur &lt;em&gt;Propri&#233;t&#233;s&amp;#8230;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Dans la fen&#234;tre qui s&amp;#8217;ouvre, cochez la case &lt;em&gt;Surveillez les nouveaux messages dans ce dossier&lt;/em&gt; :&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/thunderbird.png' alt='Thunderbird properties' /&gt;&lt;/p&gt;

&lt;p&gt;Voil&#224;, &#224; ce jour, le mieux que l&amp;#8217;on puisse faire, mais c&amp;#8217;est mieux que rien.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Comment se passer de &amp;lt;div class=&amp;quot;clear&amp;quot;&amp;gt;&amp;lt;/div&amp;gt; ?</title>
    <link href="http://blog.happynoff.fr/post/Comment-se-passer-de-div-clear" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Comment-se-passer-de-div-clear</id>
    <updated>2011-08-25T15:02:53Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Dans mon travail de tous les jours, en tant que d&#233;veloppeur web, je me retrouve confront&#233; au probl&#232;me dit de la guillotine lorsque j&amp;#8217;utilise des &#233;l&#233;ments en &lt;em&gt;float&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Pour illustrer mes propos voici un petit exemple de code et son r&#233;sultat :&lt;/p&gt;

&lt;p&gt;Code xHTML :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;id&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;container&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;class&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;content&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;class&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;content&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Code CSS :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='co'&gt;#container&lt;/span&gt; {&lt;br&gt;  &lt;span class='ke'&gt;border&lt;/span&gt;:       &lt;span class='fl'&gt;1px&lt;/span&gt; &lt;span class='vl'&gt;solid&lt;/span&gt; &lt;span class='cr'&gt;#000000&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;padding&lt;/span&gt;:      &lt;span class='fl'&gt;10px&lt;/span&gt;;&lt;br&gt;}&lt;br&gt;      &lt;br&gt;&lt;span class='cl'&gt;.content&lt;/span&gt; {&lt;br&gt;  &lt;span class='ke'&gt;background&lt;/span&gt;:   &lt;span class='cr'&gt;#999&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;float&lt;/span&gt;:        &lt;span class='vl'&gt;left&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;height&lt;/span&gt;:       &lt;span class='fl'&gt;100px&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;width&lt;/span&gt;:        &lt;span class='fl'&gt;100px&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;margin-right&lt;/span&gt;: &lt;span class='fl'&gt;10px&lt;/span&gt;;&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Voici le r&#233;sultat obtenu :&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/float_with_problem.png' alt='Float with problem' /&gt;&lt;/p&gt;

&lt;p&gt;En effet, dans 99% des cas, ce n&amp;#8217;&#233;tait pas le but recherch&#233;.&lt;/p&gt;    </summary>
    <content type="html">
&lt;p&gt;Pour corriger ce comportement il existe plusieurs solutions. La seule que je connaissais jusqu&amp;#8217;&#224; maintenant &#233;tait la technique de la &lt;em&gt;div clear&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id='technique_de_la_div_clear'&gt;Technique de la div clear&lt;/h2&gt;

&lt;p&gt;Cette technique consiste &#224; ajouter une &lt;em&gt;div&lt;/em&gt; ayant pour particularit&#233; d&amp;#8217;avoir la propri&#233;t&#233; CSS &lt;em&gt;clear: both;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Code xHTML :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;id&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;container&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;class&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;content&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;class&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;content&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;class&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;clear&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Code CSS :&lt;/p&gt;&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='co'&gt;#container&lt;/span&gt; {&lt;br&gt;  &lt;span class='ke'&gt;border&lt;/span&gt;:       &lt;span class='fl'&gt;1px&lt;/span&gt; &lt;span class='vl'&gt;solid&lt;/span&gt; &lt;span class='cr'&gt;#000000&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;padding&lt;/span&gt;:      &lt;span class='fl'&gt;10px&lt;/span&gt;;&lt;br&gt;}&lt;br&gt;      &lt;br&gt;&lt;span class='cl'&gt;.content&lt;/span&gt; {&lt;br&gt;  &lt;span class='ke'&gt;background&lt;/span&gt;:   &lt;span class='cr'&gt;#999&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;float&lt;/span&gt;:        &lt;span class='vl'&gt;left&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;height&lt;/span&gt;:       &lt;span class='fl'&gt;100px&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;width&lt;/span&gt;:        &lt;span class='fl'&gt;100px&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;margin-right&lt;/span&gt;: &lt;span class='fl'&gt;10px&lt;/span&gt;;&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span class='cl'&gt;.clear&lt;/span&gt; {&lt;br&gt;  &lt;span class='ke'&gt;clear&lt;/span&gt;: &lt;span class='vl'&gt;both&lt;/span&gt;;&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Voici le r&#233;sultat :&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/float_with_no_problem.png' alt='Float with no problem' /&gt;&lt;/p&gt;

&lt;p&gt;Cette solution permet d&amp;#8217;obtenir le r&#233;sultat voulu mais un souci subsiste, l&amp;#8217;utilisation d&amp;#8217;une balise pr&#233;sente uniquement pour le style.&amp;lt;br&amp;gt; C&amp;#8217;est mal !&lt;/p&gt;

&lt;p&gt;Voici donc une solution purement CSS se basant sur l&amp;#8217;utilisation de la propri&#233;t&#233; &lt;em&gt;overflow&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id='la_technique_overflow'&gt;La technique Overflow&lt;/h2&gt;

&lt;p&gt;Pour cette technique il suffit simplement d&amp;#8217;ajouter la propri&#233;t&#233; &lt;em&gt;overflow: hidden&lt;/em&gt; sur le conteneur.&lt;/p&gt;

&lt;p&gt;Edit: Attention ! Pensez &#224; pr&#233;ciser une &lt;em&gt;width&lt;/em&gt;, sinon la technique risque de ne pas marcher sous certains navigateurs !&lt;/p&gt;

&lt;p&gt;Code xHTML :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;id&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;container&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;class&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;content&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;class&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;content&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Code CSS :&lt;/p&gt;&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='co'&gt;#container&lt;/span&gt; {&lt;br&gt;  &lt;span class='ke'&gt;border&lt;/span&gt;:       &lt;span class='fl'&gt;1px&lt;/span&gt; &lt;span class='vl'&gt;solid&lt;/span&gt; &lt;span class='cr'&gt;#000000&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;padding&lt;/span&gt;:      &lt;span class='fl'&gt;10px&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;overflow&lt;/span&gt;:     &lt;span class='vl'&gt;hidden&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;width&lt;/span&gt;:        &lt;span class='fl'&gt;100%&lt;/span&gt;;&lt;br&gt;}&lt;br&gt;      &lt;br&gt;&lt;span class='cl'&gt;.content&lt;/span&gt; {&lt;br&gt;  &lt;span class='ke'&gt;background&lt;/span&gt;:   &lt;span class='cr'&gt;#999&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;float&lt;/span&gt;:        &lt;span class='vl'&gt;left&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;height&lt;/span&gt;:       &lt;span class='fl'&gt;100px&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;width&lt;/span&gt;:        &lt;span class='fl'&gt;100px&lt;/span&gt;;&lt;br&gt;  &lt;span class='ke'&gt;margin-right&lt;/span&gt;: &lt;span class='fl'&gt;10px&lt;/span&gt;;&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Le r&#233;sultat est le m&#234;me mais le code HTML reste canton&#233; au strict minimum ;).&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/float_with_no_problem.png' alt='Float with no problem' /&gt;&lt;/p&gt;

&lt;p&gt;Enjoy !&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>ssh: compl&#233;tion et alias</title>
    <link href="http://blog.happynoff.fr/post/ssh-completion-et-alias" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/ssh-completion-et-alias</id>
    <updated>2011-08-25T15:02:57Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Voici deux petites astuces pour am&#233;liorer l&amp;#8217;utilisation de ssh.&lt;/p&gt;

&lt;h2 id='compl&#233;tion_des_noms_dh&#244;tes'&gt;Compl&#233;tion des noms d&amp;#8217;h&#244;tes&lt;/h2&gt;

&lt;p&gt;Pour obtenir la compl&#233;tion des noms d&amp;#8217;h&#244;tes pour ssh et scp, il vous suffit d&amp;#8217;installer le paquet bash-completion.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='c'&gt;# Sous Debian et consorts&lt;/span&gt;&lt;br&gt;aptitude install bash-completion&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;# Sous Mac, avec macport&lt;/span&gt;&lt;br&gt;port install bash-completion&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;# Sous Mac, avec homebrew&lt;/span&gt;&lt;br&gt;brew install bash-completion&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='alias'&gt;Alias&lt;/h2&gt;

&lt;p&gt;Il est possible de cr&#233;er des alias pour les h&#244;tes sur lesquels on se ssh. Cela se fait en &#233;ditant le fichier &lt;em&gt;~/.ssh/config&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;Host somehost&lt;br&gt;  HostName     some.host.with.long.name&lt;br&gt;  User         someuser&lt;br&gt;  IdentityFile ~/.ssh/other_id_rsa&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Ceci permet de se connecter &#224; l&amp;#8217;h&#244;te &lt;em&gt;some.host.with.long.name&lt;/em&gt; avec l&amp;#8217;utilisateur &lt;em&gt;someuser&lt;/em&gt; en utilisant la cl&#233; &lt;em&gt;~/.ssh/other_id_rsa&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;ssh somehost&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Changer facilement la configuration proxy de SVN</title>
    <link href="http://blog.happynoff.fr/post/Changer-facilement-la-configuration-proxy-de-SVN" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Changer-facilement-la-configuration-proxy-de-SVN</id>
    <updated>2011-08-25T15:02:58Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Comme de nombreux d&#233;veloppeurs, je suis tr&#232;s souvent amen&#233; &#224; utiliser SVN (Subversion). Comme de nombreux d&#233;veloppeurs toujours, je suis amen&#233; &#224; partir en mission chez diff&#233;rents clients qui ont chacun leur proxy. Pour peu qu&amp;#8217;on en ait d&#233;j&#224; un au boulot ou chez soi, &#231;a devient vite fatiguant de jongler entre ces diff&#233;rentes configurations.&lt;/p&gt;

&lt;p&gt;Voici donc une petite astuce toute b&#234;te pour se rendre la vie facile.&lt;/p&gt;

&lt;h2 id='configurer_un_proxy_dans_subversion'&gt;Configurer un proxy dans subversion&lt;/h2&gt;

&lt;p&gt;Premi&#232;re &#233;tape, savoir o&#249; se configure les proxies dans subversion. Tout cela se passe dans le fichier ~/.subversion/servers o&#249; l&amp;#8217;on peut trouver les lignes suivantes :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='c'&gt;# http-proxy-host = &lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# http-proxy-port = 3128&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# http-proxy-username = &lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# http-proxy-password =&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Comme on peut le voir, il est facile de configurer un proxy selon le serveur svn que l&amp;#8217;on veut atteindre. C&amp;#8217;est tr&#232;s bien, seulement &#231;a ne nous aide pas. Nous ce n&amp;#8217;est pas le serveur qui change mais l&amp;#8217;environnement de travail !&lt;/p&gt;

&lt;h2 id='comment_se_sauver_la_vie'&gt;Comment se sauver la vie&lt;/h2&gt;

&lt;p&gt;Tout d&amp;#8217;abord il faut cr&#233;er un fichier servers par environnement. Id&#233;alement on les place dans le dossier ~/.subversion avec un nom comme env1_servers, env2_servers (en ce qui me concerne je prends 3 lettres repr&#233;sentatives de l&amp;#8217;environnement).&lt;/p&gt;

&lt;p&gt;Pensez &#224; renommer le fichier servers existant, en def_servers par exemple car servers va devenir un lien symbolique vers le fichier qui nous int&#233;resse.&lt;/p&gt;

&lt;p&gt;On pourrait se contenter ce &#231;a et s&amp;#8217;amuser &#224; appeler ln -s &#224; tout bout de champ, voir m&#234;me cr&#233;er un alias comme &amp;#8220;ln -s ~/.subversion/env1_servers ~/.subversion/servers&amp;#8221; mais honn&#234;tement, une solution p&#233;renne (quel horrible mot) serait bien plus agr&#233;able.&lt;/p&gt;

&lt;p&gt;Voici donc une petite fonction shell qui va nous faciliter grandement la vie !&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='c'&gt;# switch de profile svn&lt;/span&gt;&lt;br&gt;svnpro() &lt;span class='r'&gt;{&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;if&lt;/span&gt; &lt;span class='r'&gt;[&lt;/span&gt; -f ~/.subversion/&lt;span class='pc'&gt;$1&lt;/span&gt;_servers &lt;span class='r'&gt;]&lt;/span&gt;&lt;span class='dl'&gt;;&lt;/span&gt; &lt;span class='r'&gt;then&lt;/span&gt;&lt;br&gt;    ln -nfs &lt;span class='pc'&gt;$1&lt;/span&gt;_servers ~/.subversion/servers&lt;br&gt;  &lt;span class='r'&gt;else&lt;/span&gt;&lt;br&gt;    &lt;span class='fu'&gt;echo&lt;/span&gt; &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='pc'&gt;$1&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;servers n'existe pas.&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;fi&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Et voila, il nous suffit maintenant de l&amp;#8217;appeler de la mani&#232;re suivante et notre configuration de proxy changera.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;svnpro env1&lt;br&gt;svnpro env2&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Un peu de couleur dans les diffs SVN</title>
    <link href="http://blog.happynoff.fr/post/Un-peu-de-couleur-dans-les-diffs-SVN" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Un-peu-de-couleur-dans-les-diffs-SVN</id>
    <updated>2011-08-25T15:02:54Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Les diffs SVN peuvent parfois &#234;tre longs et souvent p&#233;nibles &#224; lire. Oui il y a des + et des - mais &#231;a ne fait pas tout. Un bon moyen de simplifier cette lecture est l&amp;#8217;utilisation de couleurs.&lt;/p&gt;

&lt;p&gt;Un utilitaire bien sympathique, colordiff, permet justement de coloriser l&amp;#8217;affichage des diffs. Packag&#233; sous Debian ou disponible via MacPort.&lt;/p&gt;

&lt;p&gt;Voici comment l&amp;#8217;utiliser pour les diffs SVN.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pour une utilisation occasionnelle&lt;/strong&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;svn diff --diff-cmd colordiff&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;ou&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;svn diff | colordiff&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Pour l&amp;#8217;&#233;tablir de mani&#232;re globale&lt;/strong&gt;, il suffit d&amp;#8217;&#233;diter le fichier &lt;em&gt;~/.subversion/config&lt;/em&gt; et d&amp;#8217;ajouter dans la section &lt;em&gt;&lt;span&gt;helpers&lt;/span&gt;&lt;/em&gt; :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;diff-cmd = colordiff&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;EDIT: Pour afficher la sortie de colordiff dans less, il faut utiliser l&amp;#8217;option &lt;em&gt;-R&lt;/em&gt; de ce dernier :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;svn diff | less -R&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pour aller plus loin, un autre utilitaire permet de coloriser bien plus de choses, il s&amp;#8217;agit de &lt;a href='http://colorsvn.tigris.org/' title='page du projet colorsvn'&gt;colorsvn&lt;/a&gt;.&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Ignorer les fichiers de votre IDE dans Subversion</title>
    <link href="http://blog.happynoff.fr/post/Ignorer-les-fichiers-de-votre-IDE-dans-Subversion" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Ignorer-les-fichiers-de-votre-IDE-dans-Subversion</id>
    <updated>2011-08-25T15:02:53Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Il peut arriver que, sur un projet, chacun utilise son propre IDE. Le petit probl&#232;me c&amp;#8217;est que chaque IDE cr&#233;e des fichiers qui lui sont sp&#233;cifiques. Lorsque l&amp;#8217;on utilise Subversion, g&#233;rer les &lt;em&gt;svn:ignore&lt;/em&gt; devient vite lourd. Mais une solution existe ! Ignorer localement certains fichiers.&lt;/p&gt;

&lt;p&gt;Je prendrai NetBeans comme exemple pour cet article.&lt;/p&gt;

&lt;p&gt;Voici ce que l&amp;#8217;on peut voir lors d&amp;#8217;un &lt;em&gt;svn status&lt;/em&gt; apr&#232;s la cr&#233;ation d&amp;#8217;un projet sous NetBeans depuis des sources existantes:&lt;/p&gt;
&lt;pre class='shell'&gt;&lt;kbd&gt;svn status&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;?      nbproject&lt;/samp&gt;&lt;br&gt;&lt;samp class='svn_modified'&gt;M      some\_file&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;Dans le dossier &lt;em&gt;~/.subversion&lt;/em&gt;, il existe un fichier &lt;em&gt;config&lt;/em&gt;. Dans ce fichier, sous le groupe &lt;em&gt;&lt;span&gt;miscellany&lt;/span&gt;&lt;/em&gt;, vous trouverez les lignes suivantes :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='c'&gt;## Debian&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# global-ignores = \*.o \*.lo \*.la \*.al .libs \*.so&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;#   \*.so.[0-9]\* \*.a \*.pyc \*.pyo \*.rej \*~ #\*# .#\* .\*.swp .DS\_Store&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;## Mac&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# global-ignores = \*.o \*.lo \*.la #\*# .\*.rej \*.rej&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;#  .\*~ \*~ .#\* .DS\_Store&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Il vous suffit de d&#233;commenter ces lignes et de rajouter les fichiers que vous souhaitez ignorer :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS\_Store nbproject&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Voil&#224; le r&#233;sultat :&lt;/p&gt;
&lt;pre class='shell'&gt;&lt;kbd&gt;svn status&lt;/kbd&gt;&lt;br&gt;&lt;samp class='svn_modified'&gt;M      some\_file&lt;/samp&gt;&lt;/pre&gt;    </content>
  </entry>
  <entry>
    <title>Remettre GRUB apres une reinstallation de Windows</title>
    <link href="http://blog.happynoff.fr/post/Remettre-GRUB-apres-une-reinstallation-de-Windows" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Remettre-GRUB-apres-une-reinstallation-de-Windows</id>
    <updated>2011-08-25T15:02:54Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;En g&#233;n&#233;ral, quand on me parle de remettre GRUB apr&#232;s une installation de Windows, la premi&#232;re chose &#224; laquelle je pense est &amp;#8220;bah tu mets un live-cd, tu montes ta partition /, tu te chroot et grub-install&amp;#8221;.&lt;/p&gt;

&lt;p&gt;En somme, &#231;a se r&#233;sume effectivement &#224; &#231;a. Mais, parfois, tout ne se passe pas comme pr&#233;vu. En effet, lors de ma derni&#232;re exp&#233;rience, lorsque je montais la partition / de ma Debian, aucune trace de hda ou sda. Rien du tout ! La raison, je ne la connais pas et, pour &#234;tre honn&#234;te, je n&amp;#8217;ai pas cherch&#233; (cr&#233;ation dynamique, quelque chose comme &#231;a ?).&lt;/p&gt;

&lt;p&gt;Bref, rien &#224; faire, ils sont introuvables. Voici donc la solution dans ce cas :&lt;/p&gt;

&lt;p&gt;Lancer le CD d&amp;#8217;installation de Debian (marche probablement avec d&amp;#8217;autre mais c&amp;#8217;est ce que j&amp;#8217;ai fait donc&amp;#8230;). Apr&#232;s le lancement, continuer jusqu&amp;#8217;au moment de la s&#233;lection du r&#233;seau, passer cette &#233;tape puis, un petit ALT+F2 (ou CTRL+ALT+F2), pour passer dans une console. Ensuite, voici la marche &#224; suivre (mon / se trouve dans /dev/sda6) :&lt;/p&gt;
&lt;pre class='shell'&gt;&lt;samp class='prompt'&gt;$ &lt;/samp&gt;&lt;kbd&gt;mount /dev/sda6 /mnt&lt;/kbd&gt;&lt;br&gt;&lt;samp class='prompt'&gt;$ &lt;/samp&gt;&lt;kbd&gt;mount -o bind /dev /mnt/dev&lt;/kbd&gt;&lt;br&gt;&lt;samp class='prompt'&gt;$ &lt;/samp&gt;&lt;kbd&gt;mount -o bind /proc /mnt/proc&lt;/kbd&gt;&lt;br&gt;&lt;samp class='prompt'&gt;$ &lt;/samp&gt;&lt;kbd&gt;chroot /mnt&lt;/kbd&gt;&lt;br&gt;&lt;samp class='prompt'&gt;$ &lt;/samp&gt;&lt;kbd&gt;grub&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;Probing devices to guess BIOS drives. This may take a long time.&lt;/samp&gt;&lt;br&gt;&lt;samp class='prompt'&gt;grub&gt; &lt;/samp&gt;&lt;kbd&gt;root (hd0,5)&lt;/kbd&gt; # trouv&#233; dans /boot/grub/menu.lst&lt;br&gt;&lt;samp class='prompt'&gt;grub&gt; &lt;/samp&gt;&lt;kbd&gt;setup (hd0)&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;sortie de grub qui dit que tout s'est bien pass&#233;&lt;/samp&gt;&lt;br&gt;&lt;samp class='prompt'&gt;grub&gt; &lt;/samp&gt;&lt;span class='comment'&gt;# CTRL+C pour sortir&lt;/span&gt;&lt;br&gt;&lt;samp class='prompt'&gt;$ &lt;/samp&gt;&lt;kbd&gt;update-grub&lt;/kbd&gt;&lt;br&gt;&lt;samp class='prompt'&gt;$ &lt;/samp&gt;&lt;kbd&gt;reboot&lt;/kbd&gt;&lt;/pre&gt;
&lt;p&gt;En ce qui me concerne, &#231;a a fonctionn&#233;. Seul un dernier souci que j&amp;#8217;ai eu, mes partitions /home et de swap ont &#233;t&#233; &#233;chang&#233;es. Donc, au red&#233;marrage, si un probl&#232;me se pose, pensez avant de tout envoyer valser &#224; passer en console de maintenance, &#224; tester le montage de vos partitions pour voir ce qu&amp;#8217;il y a dedans et modifier votre &lt;em&gt;/etc/fstab&lt;/em&gt; en cons&#233;quence&amp;#8230;&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Contr&#244;ler Amarok en ligne de commande grace a DCOP</title>
    <link href="http://blog.happynoff.fr/post/Controler-Amarok-en-ligne-de-commande-grace-a-DCOP" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Controler-Amarok-en-ligne-de-commande-grace-a-DCOP</id>
    <updated>2011-08-25T15:02:53Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Pendant longtemps, je me suis demand&#233; comment on pouvait r&#233;gler le son d&amp;#8217;Amarok depuis la ligne de commande.&lt;/p&gt;

&lt;p&gt;Quel int&#233;r&#234;t, me direz-vous, alors qu&amp;#8217;il suffit de cliquer pour s&amp;#8217;en occuper ?&lt;/p&gt;

&lt;p&gt;La r&#233;ponse est simple. D&amp;#8217;un naturel fain&#233;ant, il m&amp;#8217;arrive de coder au lit et de mettre Amarok en lecture sur mon PC de bureau. Il est possible de contr&#244;ler Amarok en ligne de commande pour ce qui concerne la lecture (play, pause, stop, etc&amp;#8230;). Le contr&#244;le du son ne fait malheureusement pas partie des options. C&amp;#8217;est l&#224; que DCOP sauve des vies&amp;#8230;&lt;/p&gt;    </summary>
    <content type="html">
&lt;h2 id='dcop'&gt;DCOP&lt;/h2&gt;
&lt;blockquote cite='http://fr.wikipedia.org/wiki/DCOP'&gt;
  &lt;p&gt;DCOP ( Desktop COmmunication Protocol), est un syst&#232;me de communication l&#233;ger entre les processus et les composants logiciels d'un syst&#232;me.
     Sa principale utilisation est de permettre aux diff&#233;rentes applications d'interagir et de partager des t&#226;ches complexes.
     DCOP est essentiellement un syst&#232;me de &#171; contr&#244;le &#224; distance &#187;, qui peut faire profiter une application ou un script de l'aide des autres applications.
     Il est construit au dessus du protocole d'&#233;changes interclients de X.&lt;/p&gt;
  &lt;p class='quotefrom'&gt;Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id='utilisation_damarok_via_dcop'&gt;Utilisation d&amp;#8217;Amarok via DCOP&lt;/h2&gt;

&lt;p&gt;Comme la plupart (voir toutes) des applications KDE, Amarok fournit une interface DCOP. Celle-ci est tr&#232;s compl&#232;te, soit dit en passant.&lt;/p&gt;

&lt;p&gt;Lorsque l&amp;#8217;on est en ssh, il faut tout d&amp;#8217;abord r&#233;cup&#233;rer le DISPLAY. Ceci se fait en g&#233;n&#233;ral de cette mani&#232;re :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='fu'&gt;export&lt;/span&gt; &lt;span class='iv'&gt;DISPLAY&lt;/span&gt;=&lt;span class='r'&gt;:&lt;/span&gt;&lt;span class='fl'&gt;0.0&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id='contr&#244;le_du_son'&gt;Contr&#244;le du son&lt;/h3&gt;

&lt;p&gt;La premi&#232;re raison de mon investigation &#233;tait le contr&#244;le du son, il est donc normal que je commence par l&#224;&amp;#8230;&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;dcop amarok player setVolume X&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Cette commande permet de r&#233;gler le son a X, X &#233;tant compris entre 0 et 100&lt;/p&gt;

&lt;h3 id='r&#233;cup&#233;ration_dinformations'&gt;R&#233;cup&#233;ration d&amp;#8217;informations&lt;/h3&gt;

&lt;p&gt;Toujours gr&#226;ce &#224; DCOP, il est possible de r&#233;cup&#233;rer des informations sur la playlist ou la piste actuellement en lecture. Voici un petit exemple :&lt;/p&gt;
&lt;pre class='shell'&gt;&lt;kbd&gt;dcop amarok player title&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;The Bonny Swans&lt;/samp&gt;&lt;br&gt;&lt;br&gt;&lt;kbd&gt;dcop amarok player artist&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;Loreena McKennitt&lt;/samp&gt;&lt;br&gt;&lt;br&gt;&lt;kbd&gt;dcop amarok player album&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;The Mask And The Mirror&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Vous connaissez maintenant le principe de la manipulation d&amp;#8217;Amarok via DCOP. Je vous invite donc &#224; fouiller un peu plus pour d&#233;couvrir toutes les possibilit&#233;s offertes par l&amp;#8217;interface DCOP d&amp;#8217;Amarok mais &#233;galement celles d&amp;#8217;autres applications comme Kmix. Le moyen le plus simple est d&amp;#8217;utiliser la compl&#233;tion de Bash&amp;#8230;&lt;/p&gt;

&lt;h2 id='r&#233;f&#233;rences'&gt;R&#233;f&#233;rences&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://fr.wikipedia.org/wiki/DCOP'&gt;http://fr.wikipedia.org/wiki/DCOP (fr)&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://amarok.kde.org/wiki/DCOP_Functions'&gt;http://amarok.kde.org/wiki/DCOP_Functions (en)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;    </content>
  </entry>
  <entry>
    <title>Automatiser les tags ID3 de vos mp3</title>
    <link href="http://blog.happynoff.fr/post/Automatiser-les-tags-ID3-de-vos-mp3" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Automatiser-les-tags-ID3-de-vos-mp3</id>
    <updated>2011-08-25T15:02:56Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Cet article pr&#233;sente trois petits scripts ayant pour but d&amp;#8217;appliquer automatiquement les tags ID3 sur vos mp3.&lt;/p&gt;    </summary>
    <content type="html">
&lt;h2 id='prerequis'&gt;Prerequis&lt;/h2&gt;

&lt;p&gt;Ces scripts se servent des programmes suivants :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;eyeD3 : permet l&amp;#8217;&#233;dition des tags ID3&lt;/li&gt;

&lt;li&gt;jpegoptim : optimisation des images&lt;br /&gt;(suppression des infos inutiles, pratique aussi pour les images web)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sous Debian, il existe un package pour eyeD3 ainsi que pour jpegoptim.&lt;/p&gt;

&lt;h2 id='conventions_de_nommage_des_fichiers'&gt;Conventions de nommage des fichiers&lt;/h2&gt;

&lt;p&gt;Ces scripts se basent sur des conventions de nommage que j&amp;#8217;ai &#233;tabli pour mes mp3.&lt;br /&gt;Mais elles peuvent ne pas &#234;tre du gout de tout le monde.&lt;/p&gt;

&lt;p&gt;Il suffit donc d&amp;#8217;adapter les expressions r&#233;guli&#232;res a vos conventions de nommage. Si vous n&amp;#8217;en avez pas, ces scripts n&amp;#8217;auront aucune utilit&#233; pour vous ;)&lt;/p&gt;
&lt;pre&gt;~/Music&lt;br&gt;&lt;span class='deco'&gt;&#9492;&#9472;&#9472; &lt;/span&gt;Nom_Artist&lt;br&gt;&lt;span class='deco'&gt;    &#9500;&#9472;&#9472; &lt;/span&gt;Titre_Album&lt;br&gt;&lt;span class='deco'&gt;    &#9474;   &#9492;&#9472;&#9472; &lt;/span&gt;01___Titre_Du_Morceau&lt;br&gt;&lt;span class='deco'&gt;    &#9492;&#9472;&#9472; &lt;/span&gt;Autre_Album&lt;br&gt;&lt;span class='deco'&gt;        &#9500;&#9472;&#9472; &lt;/span&gt;CD_1&lt;br&gt;&lt;span class='deco'&gt;        &#9474;   &#9492;&#9472;&#9472; &lt;/span&gt;01___Titre_Du_Morceau&lt;br&gt;&lt;span class='deco'&gt;        &#9492;&#9472;&#9472; &lt;/span&gt;CD_2&lt;br&gt;&lt;span class='deco'&gt;            &#9492;&#9472;&#9472; &lt;/span&gt;01___Titre_Du_Morceau&lt;/pre&gt;
&lt;h2 id='le_script_tag_tracks'&gt;Le script tag_tracks&lt;/h2&gt;

&lt;p&gt;Ce script se charge d&amp;#8217;appliquer les tags ID3 sur chaque mp3 du dossier.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='di'&gt;#!/usr/bin/env bash&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# expressions regulieres utilisees pour obtenir les informations&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='iv'&gt;reg_name&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;s/^&lt;/span&gt;&lt;span class='k'&gt;\(&lt;/span&gt;&lt;span class='k'&gt;[0-9]&lt;/span&gt;&lt;span class='k'&gt;\{&lt;/span&gt;&lt;span class='k'&gt;2&lt;/span&gt;&lt;span class='k'&gt;\}&lt;/span&gt;&lt;span class='k'&gt;\)&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;\(&lt;/span&gt;&lt;span class='k'&gt;.&lt;/span&gt;&lt;span class='k'&gt;\*&lt;/span&gt;&lt;span class='k'&gt;\)&lt;/span&gt;&lt;span class='k'&gt;\.&lt;/span&gt;&lt;span class='k'&gt;\(&lt;/span&gt;&lt;span class='k'&gt;mp3&lt;/span&gt;&lt;span class='k'&gt;\|&lt;/span&gt;&lt;span class='k'&gt;ogg&lt;/span&gt;&lt;span class='k'&gt;\)&lt;/span&gt;&lt;span class='k'&gt;/&lt;/span&gt;&lt;span class='k'&gt;&lt;/span&gt;&lt;span class='k'&gt;/&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class='iv'&gt;reg_artist&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;([^/]+)/[^/]+(/CD&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;[0-9]+)?&lt;/span&gt;$&amp;quot;&lt;br&gt;&lt;span class='k'&gt;reg_album=&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='r'&gt;[&lt;/span&gt;^/&lt;span class='r'&gt;]&lt;/span&gt;+(/CD\_&lt;span class='r'&gt;[&lt;/span&gt;&lt;span class='fl'&gt;0-9&lt;/span&gt;&lt;span class='r'&gt;]&lt;/span&gt;+)?$&amp;quot;&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# Si on est en dans un album compose d'un seul CD,&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# on recupere l'image Folder.jpg du dossier courant.&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# Dans le cas contraire, c'est celle du dossier parent.&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;if&lt;/span&gt; &lt;span class='r'&gt;[&lt;/span&gt; -f ./Folder.jpg &lt;span class='r'&gt;]&lt;/span&gt;&lt;span class='dl'&gt;;&lt;/span&gt; &lt;span class='r'&gt;then&lt;/span&gt;&lt;br&gt;  &lt;span class='iv'&gt;img&lt;/span&gt;=&lt;span class='s'&gt;'./Folder.jpg'&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;else&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;if&lt;/span&gt; &lt;span class='r'&gt;[&lt;/span&gt; -f ../Folder.jpg &lt;span class='r'&gt;]&lt;/span&gt;&lt;span class='dl'&gt;;&lt;/span&gt; &lt;span class='r'&gt;then&lt;/span&gt;&lt;br&gt;    &lt;span class='iv'&gt;img&lt;/span&gt;=&lt;span class='s'&gt;'../Folder.jpg'&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;fi&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;fi&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# Optimisation de l'image pour qu'elle prenne moins de place&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;jpegoptim --strip-all &lt;span class='iv'&gt;$img&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# On effectue le traitement pour chaque fichier mp3 du dossier&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;for&lt;/span&gt; fic &lt;span class='r'&gt;in&lt;/span&gt; *.mp3&lt;br&gt;&lt;span class='r'&gt;do&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;if&lt;/span&gt; &lt;span class='r'&gt;[&lt;/span&gt; -f &lt;span class='iv'&gt;$fic&lt;/span&gt; &lt;span class='r'&gt;]&lt;/span&gt;&lt;span class='dl'&gt;;&lt;/span&gt; &lt;span class='r'&gt;then&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# Recuperation des informations du fichier&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;    &lt;span class='iv'&gt;num&lt;/span&gt;=&lt;span class='sh'&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;span class='k'&gt;echo &lt;/span&gt;&lt;span class='iv'&gt;$fic&lt;/span&gt;&lt;span class='k'&gt; | sed &amp;quot;s/&lt;/span&gt;&lt;span class='k'&gt;\(&lt;/span&gt;&lt;span class='k'&gt;[0-9]&lt;/span&gt;&lt;span class='k'&gt;\{&lt;/span&gt;&lt;span class='k'&gt;1,3&lt;/span&gt;&lt;span class='k'&gt;\}&lt;/span&gt;&lt;span class='k'&gt;\)&lt;/span&gt;&lt;span class='k'&gt;.&lt;/span&gt;&lt;span class='k'&gt;\*&lt;/span&gt;&lt;span class='k'&gt;/&lt;/span&gt;&lt;span class='k'&gt;&lt;/span&gt;&lt;span class='k'&gt;/&amp;quot;&lt;/span&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class='iv'&gt;name&lt;/span&gt;=&lt;span class='sh'&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;span class='k'&gt;echo &lt;/span&gt;&lt;span class='iv'&gt;$fic&lt;/span&gt;&lt;span class='k'&gt; | sed &lt;/span&gt;&lt;span class='iv'&gt;$reg&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;name | tr -s &amp;quot;&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class='iv'&gt;artist&lt;/span&gt;=&lt;span class='sh'&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;span class='k'&gt;pwd | grep -o &lt;/span&gt;&lt;span class='iv'&gt;$reg&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;artist | cut -d'/' -f1 | tr -s '&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;'&lt;/span&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class='iv'&gt;album&lt;/span&gt;=&lt;span class='sh'&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;span class='k'&gt;pwd | grep -o &lt;/span&gt;&lt;span class='iv'&gt;$reg&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;album | cut -d'/' -f1 | tr -s '&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;'&lt;/span&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class='iv'&gt;album_num&lt;/span&gt;=&lt;span class='sh'&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;span class='k'&gt;pwd | grep -o &amp;quot;CD&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;[0-9]+&lt;/span&gt;&lt;span class='k'&gt;$&amp;quot;&lt;/span&gt;&lt;span class='k'&gt; | cut -d'&lt;/span&gt;&lt;span class='k'&gt;\_&lt;/span&gt;&lt;span class='k'&gt;' -f2&lt;/span&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;    &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# Si l'album ne contient qu'un seul CD&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;    &lt;span class='r'&gt;if&lt;/span&gt; &lt;span class='r'&gt;[&lt;/span&gt; -z &lt;span class='iv'&gt;$album&lt;/span&gt;\_num &lt;span class='r'&gt;]&lt;/span&gt;&lt;span class='dl'&gt;;&lt;/span&gt; &lt;span class='r'&gt;then&lt;/span&gt;&lt;br&gt;      &lt;span class='iv'&gt;album_num&lt;/span&gt;=&lt;span class='s'&gt;'1'&lt;/span&gt;&lt;br&gt;    &lt;span class='r'&gt;fi&lt;/span&gt;&lt;br&gt;&lt;br&gt;    &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# Application du tag ID3.&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# Si un tag existait avant, il est supprime.&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# Cela permet d'eviter l'accumulation de la meme image&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# dans le tag.&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;    eyeD3 --remove-all --to-v2.&lt;span class='i'&gt;4&lt;/span&gt; \&lt;br&gt;          -t&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='iv'&gt;$name&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; \&lt;br&gt;          -a&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='iv'&gt;$artist&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; \&lt;br&gt;          -A&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='iv'&gt;$album&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; \&lt;br&gt;          -n&lt;span class='iv'&gt;$num&lt;/span&gt; \&lt;br&gt;          --add-image=&lt;span class='iv'&gt;$img&lt;/span&gt;&lt;span class='r'&gt;:&lt;/span&gt;FRONT_COVER \&lt;br&gt;          --set-text-frame=TPOS&lt;span class='r'&gt;:&lt;/span&gt;&lt;span class='iv'&gt;$album&lt;/span&gt;\_num \&lt;br&gt;          &lt;span class='iv'&gt;$fic&lt;/span&gt; &lt;span class='i'&gt;1&lt;/span&gt;&lt;span class='bi'&gt;&amp;gt;&lt;/span&gt; /dev/null&lt;br&gt;  &lt;span class='r'&gt;fi&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;done&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='le_script_tag_album'&gt;Le script tag_album&lt;/h2&gt;

&lt;p&gt;Ce script se charge te d&amp;#8217;appeler le script tag_tracks sur chaque album d&amp;#8217;un artiste.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='di'&gt;#!/usr/bin/env bash&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# Pour chaque album&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;for&lt;/span&gt; d &lt;span class='r'&gt;in&lt;/span&gt; &lt;span class='sh'&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;span class='k'&gt;ls -x&lt;/span&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;do&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;if&lt;/span&gt; &lt;span class='r'&gt;[&lt;/span&gt; -d &lt;span class='iv'&gt;$d&lt;/span&gt; &lt;span class='r'&gt;]&lt;/span&gt;&lt;span class='dl'&gt;;&lt;/span&gt; &lt;span class='r'&gt;then&lt;/span&gt;&lt;br&gt;    &lt;span class='fu'&gt;cd&lt;/span&gt; &lt;span class='iv'&gt;$d&lt;/span&gt;&lt;br&gt;    &lt;span class='iv'&gt;line&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='iv'&gt;$d&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;    &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# Si c'est un album compose de plusieurs CDs,&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# pour chaque CD on appel le script tag\_tracks&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;    &lt;span class='r'&gt;if&lt;/span&gt; &lt;span class='r'&gt;[&lt;/span&gt; -d ./CD_* &lt;span class='r'&gt;]&lt;/span&gt;&lt;span class='dl'&gt;;&lt;/span&gt; &lt;span class='r'&gt;then&lt;/span&gt;&lt;br&gt;      &lt;span class='r'&gt;for&lt;/span&gt; &lt;span class='fu'&gt;cd&lt;/span&gt; &lt;span class='r'&gt;in&lt;/span&gt; ./CD_*&lt;br&gt;      &lt;span class='r'&gt;do&lt;/span&gt;&lt;br&gt;        &lt;span class='fu'&gt;cd&lt;/span&gt; &lt;span class='fu'&gt;$cd&lt;/span&gt; &lt;span class='bi'&gt;&amp;amp;&lt;/span&gt;&lt;span class='bi'&gt;&amp;amp;&lt;/span&gt; /chemin/vers/tag_tracks &lt;span class='i'&gt;2&lt;/span&gt;&lt;span class='bi'&gt;&amp;gt;&lt;/span&gt;&lt;span class='bi'&gt;&amp;amp;&lt;/span&gt;&lt;span class='i'&gt;1&lt;/span&gt; &lt;span class='bi'&gt;&amp;amp;&lt;/span&gt;&lt;span class='bi'&gt;&amp;amp;&lt;/span&gt; &lt;span class='iv'&gt;line&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='iv'&gt;$line&lt;/span&gt;&lt;span class='k'&gt; [OK]&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;        &lt;span class='fu'&gt;cd&lt;/span&gt; ..&lt;br&gt;      &lt;span class='r'&gt;done&lt;/span&gt;&lt;br&gt;      &lt;span class='fu'&gt;cd&lt;/span&gt; ..&lt;br&gt;&lt;br&gt;    &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# Si l'album ne contient qu'un seul CD,&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;# on appele directement le script tag\_tracks&lt;/span&gt;&lt;br&gt;    &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;    &lt;span class='r'&gt;else&lt;/span&gt;&lt;br&gt;      /chemin/vers/tag_tracks &lt;span class='i'&gt;2&lt;/span&gt;&lt;span class='bi'&gt;&amp;gt;&lt;/span&gt;&lt;span class='bi'&gt;&amp;amp;&lt;/span&gt;&lt;span class='i'&gt;1&lt;/span&gt; &lt;span class='bi'&gt;&amp;amp;&lt;/span&gt;&lt;span class='bi'&gt;&amp;amp;&lt;/span&gt; &lt;span class='iv'&gt;line&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='iv'&gt;$line&lt;/span&gt;&lt;span class='k'&gt; [OK]&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class='fu'&gt;cd&lt;/span&gt; ..&lt;br&gt;    &lt;span class='r'&gt;fi&lt;/span&gt;&lt;br&gt;    &lt;span class='fu'&gt;echo&lt;/span&gt; &lt;span class='iv'&gt;$line&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;fi&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;done&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='le_script_tag_artists'&gt;Le script tag_artists&lt;/h2&gt;

&lt;p&gt;Ce dernier script appel tag_albums pour chaque artiste de votre dossier de musique.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='di'&gt;#!/usr/bin/env bash&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# Pour chaque artiste (1 artiste = 1 dossier)&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;for&lt;/span&gt; d &lt;span class='r'&gt;in&lt;/span&gt; &lt;span class='sh'&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;span class='k'&gt;ls -x&lt;/span&gt;&lt;span class='dl'&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;do&lt;/span&gt;&lt;br&gt;  &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;  &lt;span class='c'&gt;# On entre dans le dossier&lt;/span&gt;&lt;br&gt;  &lt;span class='c'&gt;# et on fait appel au script tag\_albums&lt;/span&gt;&lt;br&gt;  &lt;span class='c'&gt;#&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;if&lt;/span&gt; &lt;span class='r'&gt;[&lt;/span&gt; -d &lt;span class='iv'&gt;$d&lt;/span&gt; &lt;span class='r'&gt;]&lt;/span&gt;&lt;span class='dl'&gt;;&lt;/span&gt; &lt;span class='r'&gt;then&lt;/span&gt;&lt;br&gt;    &lt;span class='fu'&gt;cd&lt;/span&gt; &lt;span class='iv'&gt;$d&lt;/span&gt;&lt;br&gt;    &lt;span class='iv'&gt;line&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;------------------- &lt;/span&gt;&lt;span class='iv'&gt;$d&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    /chemin/vers/tag_albums &lt;span class='bi'&gt;&amp;amp;&lt;/span&gt;&lt;span class='bi'&gt;&amp;amp;&lt;/span&gt; &lt;span class='iv'&gt;line&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='iv'&gt;$line&lt;/span&gt;&lt;span class='k'&gt; [OK]&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class='fu'&gt;echo&lt;/span&gt; &lt;span class='iv'&gt;$line&lt;/span&gt;&lt;br&gt;    &lt;span class='fu'&gt;cd&lt;/span&gt; ..&lt;br&gt;  &lt;span class='r'&gt;fi&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;done&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='en_r&#233;sum&#233;'&gt;En r&#233;sum&#233;&lt;/h2&gt;

&lt;p&gt;Vous avez donc maintenant trois scripts qui vous permettent d&amp;#8217;intervenir &#224; diff&#233;rents niveaux de votre arborescence ;)&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Connaitre les classes heritant d'une autre classe en Ruby</title>
    <link href="http://blog.happynoff.fr/post/Connaitre-les-classes-heritant-d-une-autre-classe-en-Ruby" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Connaitre-les-classes-heritant-d-une-autre-classe-en-Ruby</id>
    <updated>2011-08-25T15:02:57Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;En Ruby, pour conna&#238;tre la classe parente d&amp;#8217;une classe, un appel de m&#233;thode suffit. Malheureusement, il n&amp;#8217;existe pas de telle m&#233;thode afin d&amp;#8217;obtenir les classes h&#233;ritant d&amp;#8217;une classe donn&#233;e. Voici donc comment cr&#233;er ce comportement.&lt;/p&gt;

&lt;p&gt;Pr&#233;requis: une connaissance basique du langage Ruby est n&#233;cessaire pour comprendre certains listings de code.&lt;/p&gt;    </summary>
    <content type="html">
&lt;h2 id='petit_rappel'&gt;Petit rappel&lt;/h2&gt;

&lt;p&gt;Pour conna&#238;tre la classe parente d&amp;#8217;une classe en Ruby il suffit de faire :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;MaClasse&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='co'&gt;MaClasse&lt;/span&gt;.superclass&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; Object&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pour conna&#238;tre les anc&#234;tres d&amp;#8217;une classe il suffit de faire :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='co'&gt;MaClasse&lt;/span&gt;.ancestors&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; [MaClasse, Object, Kernel]&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='d&#233;finition_dune_m&#233;thode_de_classe'&gt;D&#233;finition d&amp;#8217;une m&#233;thode de classe&lt;/h2&gt;

&lt;p&gt;Ce que nous cherchons &#224; obtenir est une m&#233;thode de classe, le but &#233;tant de faire ceci :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;ClasseA&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='co'&gt;ClasseA&lt;/span&gt;.children&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; []&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;ClasseB&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;ClasseA&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='co'&gt;ClasseA&lt;/span&gt;.children&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; [ClasseB]&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pour d&#233;finir une m&#233;thode de classe il y &#224; deux fa&#231;ons (&#233;quivalentes) :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;MaClasse&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='pc'&gt;self&lt;/span&gt;.&lt;span class='fu'&gt;meth1&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;  &lt;span class='r'&gt;class&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class='cl'&gt;self&lt;/span&gt;&lt;br&gt;    &lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;meth2&lt;/span&gt;&lt;br&gt;    &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;La deuxi&#232;me fa&#231;on peut sembler un peu obscure m&#234;me pour quelqu&amp;#8217;un ayant de bonnes bases de Ruby&amp;#8230; Je vais donc l&amp;#8217;expliquer en d&#233;tail.&lt;/p&gt;

&lt;p&gt;En Ruby, TOUT est objet. Cela implique qu&amp;#8217;une classe elle-m&#234;me est un objet et donc&amp;#8230; une instance de classe : la classe Class (oui c&amp;#8217;est recherch&#233;&amp;#8230; mais &#231;a a le m&#233;rite d&amp;#8217;&#234;tre explicite).&lt;/p&gt;

&lt;p&gt;Cette &amp;#8220;instance&amp;#8221; n&amp;#8217;aurait aucun sens en plusieurs exemplaires, c&amp;#8217;est pourquoi c&amp;#8217;est un singletonur Wikipedia&amp;#8221;).&lt;/p&gt;

&lt;p&gt;De par l&amp;#8217;architecture m&#234;me de Ruby, il est possible d&amp;#8217;&#233;diter la d&#233;finition de ce singleton. C&amp;#8217;est ce que l&amp;#8217;on fait lorsque l&amp;#8217;on rajoute une m&#233;thode de classe.&lt;/p&gt;

&lt;p&gt;&#201;crire &lt;em&gt;class &amp;#171;&amp;#160;self&lt;/em&gt; revient donc &#224; entrer en mode d&amp;#8217;&#233;dition de ce singleton.&lt;/p&gt;

&lt;h2 id='la_m&#233;thode_inheritedby'&gt;La m&#233;thode inherited(by)&lt;/h2&gt;

&lt;p&gt;Comme dit pr&#233;c&#233;demment, une classe est une instance singleton de la classe Class. Lorsque l&amp;#8217;on regarde &lt;a href='http://www.ruby-doc.org/core/classes/Class.html'&gt;la documentation de la classe Class&lt;/a&gt;, on constate l&amp;#8217;existence d&amp;#8217;une m&#233;thode &amp;#8220;inherited&amp;#8221;. La lecture de sa documentation nous informe que c&amp;#8217;est une m&#233;thode de Callback appel&#233;e &#224; chaque fois qu&amp;#8217;une classe enfant de la classe courante est cr&#233;&#233;e.&lt;/p&gt;

&lt;p&gt;Voila qui est int&#233;ressant !!&lt;/p&gt;

&lt;h2 id='&#201;criture_de_notre_m&#233;thode_de_classe'&gt;&#201;criture de notre m&#233;thode de classe&lt;/h2&gt;

&lt;p&gt;Gr&#226;ce &#224; la m&#233;thode inherited, nous allons pouvoir &#233;crire notre m&#233;thode de classe ; de la mani&#232;re la plus simple qui soit puisque nous allons red&#233;finir cette m&#233;thode.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;MaClasse&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;class&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class='cl'&gt;self&lt;/span&gt;&lt;br&gt;    &lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;inherited&lt;/span&gt;(by)&lt;br&gt;      puts &lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;La classe &lt;/span&gt;&lt;span class='il'&gt;&lt;span class='idl'&gt;#{&lt;/span&gt;by&lt;span class='idl'&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class='k'&gt; h&#233;rite de &lt;/span&gt;&lt;span class='il'&gt;&lt;span class='idl'&gt;#{&lt;/span&gt;&lt;span class='pc'&gt;self&lt;/span&gt;.name&lt;span class='idl'&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;Enfant&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;MaClasse&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; La classe Enfant h&#233;rite de MaClasse&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Effet de bord sympathique, la m&#233;thode inherited&amp;#8230; est h&#233;rit&#233;e par la classe Enfant :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;PetitEnfant&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;Enfant&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; La classe PetitEnfant h&#233;rite de Enfant&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Bon c&amp;#8217;est bien beau tout &#231;a&amp;#8230; mais en attendant, on n&amp;#8217;a toujours pas la liste des enfants de notre classe ! J&amp;#8217;y viens&amp;#8230;&lt;/p&gt;

&lt;p&gt;Maintenant que l&amp;#8217;on sait utiliser inherited, le reste du travail est assez trivial. En voici le code :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;MaClasse&lt;/span&gt;&lt;br&gt;  &lt;span class='iv'&gt;@children&lt;/span&gt; = []&lt;br&gt;&lt;br&gt;  &lt;span class='r'&gt;class&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class='cl'&gt;self&lt;/span&gt;&lt;br&gt;    attr_reader &lt;span class='sy'&gt;:children&lt;/span&gt;&lt;br&gt;&lt;br&gt;    &lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;inherited&lt;/span&gt;(by)&lt;br&gt;      &lt;span class='iv'&gt;@children&lt;/span&gt; &amp;lt;&amp;lt; by&lt;br&gt;      by.instance_variable_set(&lt;span class='sy'&gt;:@children&lt;/span&gt;, [])&lt;br&gt;    &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Bon, &#231;a, &#231;a marche. Mais pourquoi &#231;a marche ?&lt;br /&gt;Explication :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='iv'&gt;@children&lt;/span&gt; = []&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Ici, on cr&#233;e une variable d&amp;#8217;instance, un tableau vide qui contiendra par la suite les classes enfants. Cette variable d&amp;#8217;instance appartient &#224; la classe elle-m&#234;me (l&amp;#8217;instance de Class).&lt;br /&gt;Placer cette variable dans &lt;em&gt;class &amp;#171;&amp;#160;self&lt;/em&gt; n&amp;#8217;aurait aucun sens&amp;#8230;&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;attr_reader &lt;span class='sy'&gt;:children&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;De la m&#234;me mani&#232;re que pour une classe normale, on donne acc&#232;s en lecture &#224; la variable d&amp;#8217;instance @children.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='iv'&gt;@children&lt;/span&gt; &amp;lt;&amp;lt; by&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;La classe pass&#233;e en param&#232;tre &#224; inherited, la classe h&#233;ritant de notre classe donc, est ins&#233;r&#233;e dans le tableau @children.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;by.instance_variable_set(&lt;span class='sy'&gt;:@children&lt;/span&gt;, [])&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Cette ligne fait en sorte que la classe enfant contienne une variable @children d&#233;j&#224; initialis&#233;e &#224; &lt;span /&gt;. Ceci &#233;vite de devoir r&#233;&#233;crire la ligne &lt;em&gt;@children = &lt;span /&gt;&lt;/em&gt; &#224; chaque fois.&lt;/p&gt;

&lt;h2 id='aller_plus_loin'&gt;Aller plus loin&amp;#8230;&lt;/h2&gt;

&lt;h3 id='g&#233;n&#233;raliser_ce_fonctionnement'&gt;G&#233;n&#233;raliser ce fonctionnement&lt;/h3&gt;

&lt;p&gt;&#201;tant donn&#233; qu&amp;#8217;il est possible d&amp;#8217;&#233;diter n&amp;#8217;importe quelle classe en Ruby, pourquoi ne pas g&#233;n&#233;raliser notre fonctionnement &#224; toutes les classes ?&lt;/p&gt;

&lt;p&gt;Ceci se fait tr&#232;s simplement en &#233;ditant la classe la plus haut plac&#233;e, j&amp;#8217;ai nomm&#233; Object :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;Object&lt;/span&gt;&lt;br&gt;  &lt;span class='iv'&gt;@children&lt;/span&gt; = []&lt;br&gt;&lt;br&gt;  &lt;span class='r'&gt;class&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class='cl'&gt;self&lt;/span&gt;&lt;br&gt;    attr_reader &lt;span class='sy'&gt;:children&lt;/span&gt;&lt;br&gt;&lt;br&gt;    &lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;inherited&lt;/span&gt;(by)&lt;br&gt;      &lt;span class='iv'&gt;@children&lt;/span&gt; &amp;lt;&amp;lt; by&lt;br&gt;      by.instance_variable_set(&lt;span class='sy'&gt;:@children&lt;/span&gt;, [])&lt;br&gt;    &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;  &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;MaClasse&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='co'&gt;Object&lt;/span&gt;.children&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; [MaClasse]&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;Enfant&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;MaClasse&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='co'&gt;MaClasse&lt;/span&gt;.children&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; [Enfant]&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id='d&#233;couvrir_toute_la_hi&#233;rarchie'&gt;D&#233;couvrir toute la hi&#233;rarchie&lt;/h3&gt;

&lt;p&gt;Pourquoi ne pas &lt;a href='http://www.youtube.com/watch?v=WtvUJURQDlU'&gt;pousser le bouchon encore plus loin Maurice&lt;/a&gt; ? Et si on faisait en sorte de r&#233;cup&#233;rer toute la descendance d&amp;#8217;une classe ?&lt;br /&gt;C&amp;#8217;est parti !&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;MaClasse&lt;/span&gt;&lt;br&gt;    &lt;span class='iv'&gt;@children&lt;/span&gt; = []&lt;br&gt;&lt;br&gt;    &lt;span class='r'&gt;class&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class='cl'&gt;self&lt;/span&gt;&lt;br&gt;        attr_reader &lt;span class='sy'&gt;:children&lt;/span&gt;&lt;br&gt;&lt;br&gt;        &lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;inherited&lt;/span&gt;(by)&lt;br&gt;            &lt;span class='iv'&gt;@children&lt;/span&gt; &amp;lt;&amp;lt; by&lt;br&gt;            by.instance_variable_set(&lt;span class='sy'&gt;:@children&lt;/span&gt;, [])&lt;br&gt;        &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;        &lt;span class='r'&gt;def&lt;/span&gt; &lt;span class='fu'&gt;all_children&lt;/span&gt;&lt;br&gt;            result = {}&lt;br&gt;            &lt;span class='iv'&gt;@children&lt;/span&gt;.each &lt;span class='r'&gt;do&lt;/span&gt; |child|&lt;br&gt;                result[child] = child.all_children&lt;br&gt;            &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;            result.empty? ? &lt;span class='pc'&gt;nil&lt;/span&gt; : result&lt;br&gt;        &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;    &lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;Enfant&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;MaClasse&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;PetitEnfant&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;Enfant&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='r'&gt;class&lt;/span&gt; &lt;span class='cl'&gt;AutreClasse&lt;/span&gt; &amp;lt; &lt;span class='co'&gt;MaClasse&lt;/span&gt;&lt;br&gt;&lt;span class='r'&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class='co'&gt;MaClasse&lt;/span&gt;.all_children&lt;br&gt;&lt;span class='c'&gt;# =&amp;gt; {Enfant=&amp;gt;{PetitEnfant=&amp;gt;nil}, AutreClasse=&amp;gt;nil}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;D&#233;j&#224; !? Et oui&amp;#8230; c&amp;#8217;est aussi simple que &#231;a&amp;#8230; :)&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>VirtualBox - BSoD au demarrage de Windows</title>
    <link href="http://blog.happynoff.fr/post/VirtualBox-BSoD-au-demarrage-de-Windows" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/VirtualBox-BSoD-au-demarrage-de-Windows</id>
    <updated>2011-08-25T15:02:56Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Si, comme moi, vous &#234;tes passe &#224; la nouvelle version de VirtualBox, celle de Sun, vous avez peut-&#234;tre de petits probl&#232;mes avec vos anciennes VM Windows.&lt;br /&gt;Voici comment r&#233;soudre le probl&#232;me du BSoD juste apr&#232;s l&amp;#8217;affichage du logo Windows.&lt;/p&gt;

&lt;p&gt;La manipulation est relativement simple. Il vous suffit d&amp;#8217;aller des les r&#233;glages de votre VM. Puis dans la partie &lt;em&gt;General&amp;#160;&amp;#187; Advanced&amp;#160;&amp;#187; IDE Controller Type&lt;/em&gt; de choisir &lt;em&gt;PIIX3&lt;/em&gt; a la place de &lt;em&gt;PIIX4&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/vbox_bsod.png' alt='r&#233;glages &#224; effectuer dans VirtualBox' /&gt;&lt;/p&gt;

&lt;p&gt;Et voil&#224; le tour est jou&#233; !&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Mettre en place un serveur SVN disponible via HTTP</title>
    <link href="http://blog.happynoff.fr/post/Mettre-en-place-un-serveur-SVN-disponible-via-HTTP" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Mettre-en-place-un-serveur-SVN-disponible-via-HTTP</id>
    <updated>2011-08-25T15:02:52Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Cet article explique comment installer SVN, creer un depot et le rendre accessible par internet via HTTP grace au serveur Apache.&lt;/p&gt;    </summary>
    <content type="html">
&lt;h2 id='installation_de_subversion_svn'&gt;Installation de Subversion (SVN)&lt;/h2&gt;

&lt;p&gt;L&amp;#8217;installation de Subversion est assez simple :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;sudo aptitude install subversion&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='cr&#233;ation_dun_d&#233;pot_svn'&gt;Cr&#233;ation d&amp;#8217;un d&#233;pot SVN&lt;/h2&gt;

&lt;p&gt;Pour initialiser un d&#233;p&#244;t SVN, il faut utiliser la commande suivante :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;svnadmin create mon_depot&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Suite &#224; cette commande, un dossier mon_depot est cr&#233;&#233; et contient l&amp;#8217;arborescence n&#233;cessaire au fonctionnement du d&#233;p&#244;t.&lt;/p&gt;

&lt;h2 id='mise_a_disposition_via_http'&gt;Mise a disposition via HTTP&lt;/h2&gt;

&lt;p&gt;Cette &#233;tape n&#233;cessite qu&amp;#8217;un serveur Apache soit install&#233; et configur&#233; sur le serveur SVN. Afin de permettre une authentification des utilisateurs un module apache est n&#233;cessaire. Il s&amp;#8217;agit de libapache2-svn.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;sudo aptitude install libapache2-svn&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Configurons maintenant Apache pour lui indiquer le comportement &#224; suivre concernant notre d&#233;p&#244;t. Dans la configuration des VirtualHosts d&amp;#8217;Apache (/etc/apache2/sites-available), imaginons que vous avez un h&#244;te d&#233;di&#233; aux d&#233;p&#244;ts svn.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&amp;lt;VirtualHost *&amp;gt;&lt;br&gt;  ServerName svn.mon_serveur.com&lt;br&gt;  &amp;lt;Location /mon_depot&amp;gt;&lt;br&gt;      DAV svn&lt;br&gt;      SVNPath /chemin/vers/mon_depot&lt;br&gt;      AuthType Basic&lt;br&gt;      AuthName &amp;quot;Mon Super Depot SVN&amp;quot;&lt;br&gt;      AuthUserFile /chemin/vers/mon_depot.htpasswd&lt;br&gt;      Require valid-user&lt;br&gt;      AuthzSVNAccessFile /chemin/vers/mon_depot.perm&lt;br&gt;  &amp;lt;/Location&amp;gt;&lt;br&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Voyons une &#224; une les lignes pr&#233;c&#233;dentes :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&amp;lt;Location /mon_depot&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Nous d&#233;clarons l&amp;#8217;acc&#232;s au d&#233;p&#244;t par l&amp;#8217;url http://svn.mon_serveur.com/mon_depot&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;DAV svn&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On signal l&amp;#8217;utilisation du module Dav pour l&amp;#8217;acc&#232;s aux fichiers via Apache&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;SVNPath /chemin/vers/mon_depot&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Donne le chemin vers le d&#233;p&#244;t&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;AuthType Basic&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On demande une authentification basique&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;AuthName&amp;quot;Mon Super Depot SVN&amp;quot;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Permet de donner un nom au serveur SVN.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;AuthUserFile /chemin/vers/mon_depot.htpasswd&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Si vous souhaitez utiliser un syst&#232;me de login/password pour l&amp;#8217;acc&#232;s au sources, vous pouvez utiliser un fichier de type htpasswd.&lt;/p&gt;

&lt;p&gt;Pour le cr&#233;er, il suffit de taper ceci&lt;/p&gt;
&lt;pre class='shell'&gt;&lt;kbd&gt;htpasswd -mc mon_depot.htpasswd mon_user&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;New password:&lt;/samp&gt;&lt;br&gt;&lt;samp&gt;Re-type new password:&lt;/samp&gt;&lt;br&gt;&lt;samp&gt;Adding password for user mon_user&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;L&amp;#8217;option -m permet de forcer l&amp;#8217;encryptage &lt;em&gt;md5&lt;/em&gt; des mots de passes. Pour d&amp;#8217;autres options, un petit &lt;em&gt;man htpasswd&lt;/em&gt; ne fait jamais de mal&amp;#8230;&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;Require valid-user&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Force les utilisateurs &#224; &#234;tre authentifi&#233;s pour effectuer des actions sur le d&#233;p&#244;t&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;AuthzSVNAccessFile /chemin/vers/mon_depot.perm&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Permet de sp&#233;cifier un fichier charg&#233; d&amp;#8217;attribuer des permissions aux utilisateurs. Son contenu est du type :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;[groups]&lt;br&gt;dev = mon_user, autre_user # cr&#233;e le groupe dev&lt;br&gt;&lt;br&gt;[/]                        # permissions pour de dossier racine du d&#233;p&#244;t&lt;br&gt;@dev = rw                  # lecture/&#233;criture pour le groupe dev&lt;br&gt;une_personne = rw          # lecture pour une_personne&lt;br&gt;anonymous =                # aucun droits pour les personnes anonymes&lt;br&gt;[/sous_dossier]            # permissions pour le dossier /sous_dossier&lt;br&gt;@dev = r                   # droit de lecture pour le groupe dev&amp;lt;/pre&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id='derni&#232;res_notes'&gt;Derni&#232;res notes&lt;/h2&gt;

&lt;p&gt;Pensez &#224; donner les droits d&amp;#8217;acc&#232;s &#224; l&amp;#8217;utilisateur d&amp;#8217;Apache sur votre d&#233;p&#244;t&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;sudo chown -R www-data&lt;span class='r'&gt;:&lt;/span&gt;www-data /chemin/vers/mon_depot&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pensez &#224; bien mettre un liens vers votre &lt;em&gt;VirtualHost&lt;/em&gt; dans &lt;em&gt;/etc/apache2/sites-enabled&lt;/em&gt;&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;ln -s /etc/apache2/sites-available/mon_vhost.conf \&lt;br&gt;  /etc/apache2/sites-enabled/&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Ou plus simplement&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;a2ensite mon_vhost.conf&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pensez &#224; red&#233;marrer le serveur Apache pour que les modifications soient prises en compte.&lt;/p&gt;

&lt;h2 id='importer_les_fichiers_sur_le_serveur'&gt;Importer les fichiers sur le serveur&lt;/h2&gt;

&lt;p&gt;Prenons un exemple simple, on dispose d&amp;#8217;un dossier de travail&lt;/p&gt;
&lt;pre&gt;mon_dossier/&lt;br&gt;   -- main.c&lt;br&gt;   -- fichier.h&lt;/pre&gt;
&lt;p&gt;Pour importer les fichiers sur le serveur :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='fu'&gt;cd&lt;/span&gt; ~/mon_dossier&lt;br&gt;svn import &lt;span class='r'&gt;. http://svn.mon_serveur.com/mon_depot&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On trouve maintenant nos deux fichiers &#224; la racine du d&#233;p&#244;t.&lt;/p&gt;

&lt;p&gt;Pour cr&#233;er une copie de travail versionn&#233;e (mon_dossier n&amp;#8217;est pas versionn&#233;) :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;svn checkout http&lt;span class='r'&gt;:&lt;/span&gt;//svn.mon_serveur.com/mon_depot&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Ceci a pour effet de cr&#233;er un dossier mon_depot dans le dossier courant. Ce dossier est une copie de travail qui pourra &#234;tre synchronis&#233;e avec le serveur lors des commits.&lt;/p&gt;

&lt;p&gt;Et voil&#224;, c&amp;#8217;est termin&#233;&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Ouvrir les liens de Thunderbird dans Firefox</title>
    <link href="http://blog.happynoff.fr/post/Ouvrir-les-liens-de-Thunderbird-dans-Firefox" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Ouvrir-les-liens-de-Thunderbird-dans-Firefox</id>
    <updated>2011-08-25T15:02:57Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Si comme moi, le fait que Konqueror (par exemple) s&amp;#8217;ouvre quand vous cliquez sur un lien dans Thunderbird vous insupporte, voici comment rem&#233;dier &#224; ce probl&#232;me.&lt;/p&gt;

&lt;p&gt;A ma connaissance il y a deux m&#233;thodes.&lt;/p&gt;    </summary>
    <content type="html">
&lt;h2 id='la_m&#233;thode_brutale'&gt;La m&#233;thode brutale&lt;/h2&gt;

&lt;p&gt;La m&#233;thode brutale consiste &#224; aller dans la configuration de Thunderbird et modifier la valeur d&amp;#8217;un param&#232;tre en dur.&amp;lt;br&amp;gt; Pour ce faire, allez dans &#233;dition &amp;gt; pr&#233;f&#233;rences &amp;gt; Avanc&#233; et cliquez sur le bouton &amp;#8216;Config Editor&amp;#8230;&amp;#8217;&lt;/p&gt;

&lt;p&gt;Une nouvelle fen&#234;tre s&amp;#8217;ouvre avec pour titre about:config. Dans celle-ci cherchez la cl&#233; &amp;#8216;network.protocol-handler.app.http&amp;#8217;&amp;lt;br&amp;gt; Si tout se passe bien, vous devriez avoir deux r&#233;ponses :&lt;/p&gt;
&lt;pre&gt;&lt;var&gt;network.protocol-handler.app.http&lt;/var&gt;&lt;br&gt;&lt;var&gt;network.protocol-handler.app.https&lt;/var&gt;&lt;/pre&gt;
&lt;p&gt;Il suffit de changer les valeurs de ces deux cl&#233;s avec le chemin vers firefox, /usr/bin/firefox (ou /usr/bin/iceweasel pour Debian).&lt;/p&gt;

&lt;h2 id='la_bonne_m&#233;thode'&gt;La bonne m&#233;thode&lt;/h2&gt;

&lt;p&gt;Ouvrez une console et tapez ceci :&lt;/p&gt;
&lt;pre class='shell'&gt;&lt;kbd&gt;sudo update-alternatives --config x-www-browser&lt;/kbd&gt;&lt;br&gt;&lt;samp&gt;Il y a 3 alternatives fournissant &#171; x-www-browser &#187;.&lt;br&gt;S&#233;lection    Alternative&lt;br&gt;-----------------------------------------------&lt;br&gt;*+        1    &lt;var&gt;/usr/bin/konqueror&lt;/var&gt;&lt;br&gt;          2    &lt;var&gt;/usr/bin/iceweasel (ou /usr/bin/firefox...)&lt;/var&gt;&lt;br&gt;          3    &lt;var&gt;/usr/bin/opera&lt;/var&gt;&lt;br&gt;Appuyez sur Entr&#233;e pour conserver la valeur par d&#233;faut[*]&lt;br&gt;ou choisissez le num&#233;ro s&#233;lectionn&#233; : &lt;/samp&gt;&lt;kbd&gt;2&lt;/kbd&gt;&lt;/pre&gt;
&lt;p&gt;Et voil&#224;, le tour est jou&#233;&amp;#8230;&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Utiliser plusieurs fois le meme VDI sous VirtualBox</title>
    <link href="http://blog.happynoff.fr/post/Utiliser-plusieurs-fois-le-meme-VDI-sous-VirtualBox" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Utiliser-plusieurs-fois-le-meme-VDI-sous-VirtualBox</id>
    <updated>2011-08-25T15:02:53Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Pendant un instant, j&amp;#8217;ai crus qu&amp;#8217;il n&amp;#8217;&#233;tait pas possible d&amp;#8217;utiliser plusieurs fois un m&#234;me fichier VDI avec VirtualBox.&lt;/p&gt;

&lt;p&gt;En effet lorsque je copiais simplement une machine virtuelle, VirtualBox me disait que cette machine &#233;tait d&#233;j&#224; enregistr&#233;e.&lt;/p&gt;

&lt;p&gt;Cette id&#233;e allant &#224; l&amp;#8217;encontre du principe m&#234;me de la virtualisation, je me suis pench&#233; sur le probl&#232;me.&lt;/p&gt;

&lt;p&gt;Il se trouve que VirtualBox est livr&#233; avec un utilitaire : VBoxManage&lt;/p&gt;

&lt;p&gt;VBoxManage permet diff&#233;rentes actions sur les fichiers VDI dont le &amp;#8216;clonevdi&amp;#8217; qui justement r&#233;pond au besoin de copie des machines virtuelles.&lt;/p&gt;

&lt;p&gt;La commande suivante permet de cr&#233;er un clone de MachineEnEntree :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;VBoxManage clonevdi MachineEnEntree.vdi MachineEnSortie.vdi&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>La Text User Interface de GDB</title>
    <link href="http://blog.happynoff.fr/post/Text-User-Interface-de-gdb" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Text-User-Interface-de-gdb</id>
    <updated>2011-08-25T15:02:54Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Petite chose que j&amp;#8217;ai d&#233;couverte il y &#224; quelques jours. Si vous programmez en C/C++, vous utilisez peut &#234;tre gdb pour debugger vos programmes. Une fonctionnalit&#233; agr&#233;able de gdb est son interface en mode text &amp;#8216;tui&amp;#8217;.&lt;/p&gt;    </summary>
    <content type="html">
&lt;p&gt;Pour la lancer en m&#234;me temps que gdb&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;gdb -tui mon_programme&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pour l&amp;#8217;activer alors que gdb est lanc&#233; le raccourcis clavier est Ctrl-x Ctrl-a.&lt;/p&gt;

&lt;p&gt;Pour tirer pleinement partie de cette fonctionnalit&#233;, ajoutez les flags de debug &#224; la compilation (-g suffit).&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/gdbtui.jpg' alt='gdb avec tui' /&gt;&lt;br /&gt; GDB en mode TUI (cliquez pour agrandir)&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Un man kikoolol</title>
    <link href="http://blog.happynoff.fr/post/Un-man-kikoolol" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Un-man-kikoolol</id>
    <updated>2011-08-25T15:02:58Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <content type="html">
&lt;p&gt;Si vous &#234;tes int&#233;ress&#233; par un man en couleurs, voici un moyen de l&amp;#8217;obtenir.&lt;/p&gt;

&lt;p&gt;Commencez par installer most. Most est un pager assez sympa dans le style de more et less.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;sudo aptitude install most&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pour faire un simple test.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;man -P most commande&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Si &#231;a vous pla&#238;t et que vous comptez le garder voici la marche &#224; suivre.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;sudo update-alternatives --config pager&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Choisissez most&lt;/p&gt;

&lt;p&gt;Si most vous pla&#238;t mais que les couleurs vous insupportent vous pouvez les d&#233;sactiver en r&#233;glant la variable d&amp;#8217;environnement MOST_SWITCHES&amp;lt;br&amp;gt; (dans votre .&lt;em&gt;shrc par exemple)&lt;/em&gt;&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;&lt;span class='fu'&gt;export&lt;/span&gt; &lt;span class='iv'&gt;MOST_SWITCHES&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;-C&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
  <entry>
    <title>Une signature dans le style de Tron</title>
    <link href="http://blog.happynoff.fr/post/Une-signature-dans-le-style-de-Tron" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Une-signature-dans-le-style-de-Tron</id>
    <updated>2011-08-25T15:02:55Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;p&gt;Petit tuto pour expliquer comment faire ceci :&lt;br /&gt; (repris d&amp;#8217;un tuto que j&amp;#8217;avais &#233;crit sur Crystal XP)&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_11.png' alt='Signature Tron' /&gt;&lt;/p&gt;    </summary>
    <content type="html">
&lt;p&gt;Pour ceux qui ne connaissent pas, un petit tour sur &lt;a href='http://www.internationalhero.co.uk/t/tron.jpg'&gt;http://www.internationalhero.co.uk/t/tron.jpg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Et oui&amp;#8230; le mec est ridicule, le film n&amp;#8217;en reste pas moins culte pour tout geek qui se respecte :)&lt;/p&gt;

&lt;p&gt;Voici donc la marche &#224; suivre :&lt;/p&gt;

&lt;p&gt;Avant de commencer, je vous conseille de r&#233;cup&#233;rer la police Tron sur dafont.com. &lt;a href='http://www.dafont.com/fr/tron.font'&gt;http://www.dafont.com/fr/tron.font&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pour le tuto j&amp;#8217;ai pris une image transparente de 280x70&lt;/p&gt;

&lt;h2 id='cr&#233;er_le_fond'&gt;Cr&#233;er le fond&lt;/h2&gt;

&lt;p&gt;Renommez le premier calque en &lt;strong&gt;bleu clair&lt;/strong&gt;. Pour ce faire, allez sur la liste des calques et double cliquez sur son nom.&lt;/p&gt;

&lt;p&gt;On commence par une s&#233;lection de tout, S&#233;lection &amp;gt; Tout (ou ctrl-A).&lt;/p&gt;

&lt;p&gt;Ensuite on r&#233;duit la s&#233;lection de 5px, S&#233;lection &amp;gt; R&#233;duire.&lt;/p&gt;

&lt;p&gt;Puis on arrondi les bords, S&#233;lection &amp;gt; Rectangle arrondi.&lt;/p&gt;

&lt;p&gt;S&#233;lectionnez un rayon entre 20% et 50%.&lt;/p&gt;

&lt;p&gt;Remplissez ensuite la s&#233;lection d&amp;#8217;un bleu clair (#CDFBFF), &#201;dition &amp;gt; Remplir avec la couleur de PP (ctrl-,).&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_01.png' alt='Tutoriel Tron, Image 01' /&gt;&lt;/p&gt;

&lt;p&gt;Faites Calque &amp;gt; Transparence &amp;gt; Alpha vers s&#233;lection.&lt;/p&gt;

&lt;p&gt;Cr&#233;ez un nouveau calque transparent et nommez le &lt;strong&gt;bleu fonc&#233;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Remplissez ensuite la s&#233;lection d&amp;#8217;un bleu tr&#232;s fonce (#2F3839).&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_02.png' alt='Tutoriel Tron, Image 02' /&gt;&lt;/p&gt;

&lt;p&gt;Cr&#233;ez un nouveau calque transparent, au dessus des deux autres et nommez le &lt;strong&gt;d&#233;grad&#233;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Reprenez le noir comme couleur de Premier Plan.&lt;/p&gt;

&lt;p&gt;Une nouvelle fois Alpha vers s&#233;lection sur un des deux autres calques, peu importe lequel.&lt;/p&gt;

&lt;p&gt;Revenez sur le calque &lt;strong&gt;d&#233;grad&#233;&lt;/strong&gt; et appliquez un d&#233;grad&#233; PP vers AP comme ceci (de bas en haut) :&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_03.png' alt='Tutoriel Tron, Image 03' /&gt;&lt;/p&gt;

&lt;p&gt;Passez le calque en mode Superposer.&lt;/p&gt;

&lt;p&gt;Puis fusionnez &lt;strong&gt;d&#233;grad&#233;&lt;/strong&gt; avec &lt;strong&gt;bleu fonc&#233;&lt;/strong&gt;. Cela se fait en faisant un clic droit sur le calque &lt;strong&gt;d&#233;grad&#233;&lt;/strong&gt; et en choisissant &lt;strong&gt;fusionnez vers le bas&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vous devriez obtenir ceci :&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_04.png' alt='Tutoriel Tron, Image 04' /&gt;&lt;/p&gt;

&lt;h2 id='cr&#233;er_la_forme'&gt;Cr&#233;er la forme&lt;/h2&gt;

&lt;p&gt;Cr&#233;ez maintenant le texte. S&#233;lectionnez la nouvelle police Tron.&lt;/p&gt;

&lt;p&gt;Ajoutez votre texte et donnez lui la taille d&#233;sir&#233;e.&lt;/p&gt;

&lt;p&gt;Afin de recentrer le texte un fois cr&#233;&#233;,&lt;/p&gt;

&lt;p&gt;Calque &amp;gt; Aligner les calques visibles :&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_05.png' alt='Tutoriel Tron, Image 05' /&gt;&lt;/p&gt;

&lt;p&gt;Sur le calque de texte, Alpha vers s&#233;lection&lt;/p&gt;

&lt;p&gt;S&#233;lectionnez le calque &lt;strong&gt;bleu fonc&#233;&lt;/strong&gt; puis,&lt;/p&gt;

&lt;p&gt;&#201;dition &amp;gt; Effacer (ctrl-K).&lt;/p&gt;

&lt;p&gt;Masquez le calque de texte (ou supprimez le&amp;#8230;).&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_06.png' alt='Tutoriel Tron, Image 06' /&gt;&lt;/p&gt;

&lt;p&gt;Cr&#233;ez un nouveau calque transparent et nommez le &lt;strong&gt;formes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sur ce calque cr&#233;ez diff&#233;rentes formes que vous souhaitez ajouter &#224; l&amp;#8217;image.&lt;/p&gt;

&lt;p&gt;Un fois termin&#233;, Alpha vers s&#233;lection sur le calque &lt;strong&gt;formes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sur le calque &lt;strong&gt;d&#233;grad&#233;&lt;/strong&gt;, &#201;dition &amp;gt; Effacer.&lt;/p&gt;

&lt;p&gt;Vous pouvez effacer le calque &lt;strong&gt;formes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_07.png' alt='Tutoriel Tron, Image 07' /&gt;&lt;/p&gt;

&lt;h2 id='et_la_lumi&#232;re_fut'&gt;Et la lumi&#232;re fut&lt;/h2&gt;

&lt;p&gt;Cr&#233;ez maintenant un calque juste en dessous du calque de d&#233;grad&#233; et nommez le &lt;strong&gt;lumi&#232;re&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Alpha vers s&#233;lection sur le calque de &lt;strong&gt;bleu fonc&#233;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sur le calque &lt;strong&gt;lumi&#232;re&lt;/strong&gt;, Agrandir la s&#233;lection de 1px, S&#233;lection &amp;gt; Agrandir.&lt;/p&gt;

&lt;p&gt;Remplissez ensuite la s&#233;lection de blanc, &#201;dition &amp;gt; Remplir avec la couleur d&amp;#8217;AP (ctrl-.).&lt;/p&gt;

&lt;p&gt;Des&#233;lectionnez tout, S&#233;lection &amp;gt; Aucune (ctrl-maj-A).&lt;/p&gt;

&lt;p&gt;Appliquez ensuite un flou Gaussien de 5px, Filtres &amp;gt; Flou &amp;gt; Flou Gaussien.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_08.png' alt='Tutoriel Tron, Image 08' /&gt;&lt;/p&gt;

&lt;p&gt;Cr&#233;ez un nouveau calque transparent au dessus de tous les autres calques.&lt;/p&gt;

&lt;p&gt;Alpha vers s&#233;lection sur le calque &lt;strong&gt;bleu fonc&#233;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Remplissez ensuite la s&#233;lection de blanc sur le nouveau calque.&lt;/p&gt;

&lt;p&gt;Inversez la s&#233;lection, S&#233;lection &amp;gt; Inverser (ctrl-I).&lt;/p&gt;

&lt;p&gt;Ajoutez un masque de calque, Calque &amp;gt; Masque &amp;gt; Ajouter masque de calque.&lt;/p&gt;

&lt;p&gt;Choisissez l&amp;#8217;option S&#233;lection (le blanc devrait disparaitre).&lt;/p&gt;

&lt;p&gt;Des&#233;lectionnez tout.&lt;/p&gt;

&lt;p&gt;Appliquez ensuite au &lt;strong&gt;masque de calque&lt;/strong&gt; un flou Gaussien de 5px.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_09.png' alt='Tutoriel Tron, Image 09' /&gt;&lt;/p&gt;

&lt;p&gt;Voila c&amp;#8217;est termin&#233;.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/tuto_tron/tuto_tron_10.png' alt='Tutoriel Tron, Image 10' /&gt; &lt;img src='/images/tuto_tron/tuto_tron_11.png' alt='Tutoriel Tron, Image 11' /&gt;&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Installer et configurer Apache2 sous Debian</title>
    <link href="http://blog.happynoff.fr/post/Installer-et-configurer-Apache2-sous-Debian" rel="alternate"/>
    <id>http://blog.happynoff.fr/post/Installer-et-configurer-Apache2-sous-Debian</id>
    <updated>2011-08-25T15:02:57Z</updated>
    <author>
      <name>Simon COURTOIS</name>
    </author>
    <summary type="html">
&lt;ul&gt;
&lt;li&gt;Installer apache2&lt;/li&gt;

&lt;li&gt;Configuration basique du serveur&lt;/li&gt;

&lt;li&gt;Gestion des VirtualHosts&lt;/li&gt;
&lt;/ul&gt;    </summary>
    <content type="html">
&lt;h2 id='premi&#232;re_chose_&#224;_faire__installer_apache2'&gt;Premi&#232;re chose &#224; faire : installer apache2&lt;/h2&gt;

&lt;p&gt;Pour ceux qui n&amp;#8217;aiment pas la console :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lancez votre gestionnaire de packages (Adept/Synaptic/etc&amp;#8230;)&lt;/li&gt;

&lt;li&gt;cherchez le package apache2 et demandez son installation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pour les autres :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;sudo aptitude install apache2&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Par d&#233;faut, sous Debian, la racine du serveur se trouve dans /var/www, les fichiers de configuration dans /etc/apache2.&lt;/p&gt;

&lt;p&gt;En ouvrant votre navigateur pr&#233;f&#233;r&#233; vous devriez atteindre votre serveur en tapant l&amp;#8217;adresse &lt;a href='http://localhost'&gt;http://localhost&lt;/a&gt; ou &lt;a href='http:
//127.0.0.1'&gt;http://127.0.0.1&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='configuration_basique_du_serveur'&gt;Configuration basique du serveur&lt;/h2&gt;

&lt;p&gt;Apr&#232;s avoir effectu&#233; un changement, il faut red&#233;marrer le serveur pour que celui-ci soit pris en compte.&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;sudo /etc/init.d/apache2 force-reload&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Changer le r&#233;pertoire racine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&#233;diter le fichier /etc/apache2/sites-enabled/000-default&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;sans se soucier du reste remplacer&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;DocumentRoot /var/www par DocumentRoot /un/autre/chemin&lt;/li&gt;

&lt;li&gt;&amp;#60;Directory /var/www&amp;#62; par &amp;#60;Directory /un/autre/chemin&amp;#62;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='gestion_des_virtualhosts'&gt;Gestion des VirtualHosts&lt;/h2&gt;

&lt;p&gt;Il peut arriver que sur votre serveur vous h&#233;bergiez plusieurs sites en m&#234;me temps. Mais comment faire la diff&#233;rence entre les requ&#234;tes ? C&amp;#8217;est justement la que les VirutalHosts interviennent.&lt;/p&gt;

&lt;p&gt;Prenons un cas pratique. Je souhaite h&#233;berger deux sites, http://www.mon_site1.com et http://www.mon_site2.com sur le m&#234;me serveur. La racine de mon_site1 se trouve dans /var/www/site1 et celle de mon_sit e2 dans /home/moi/www.&lt;/p&gt;

&lt;p&gt;Le fichier &lt;em&gt;/etc/apache2/sites-enabled/000-default&lt;/em&gt; devrait ressembler a ceci (j&amp;#8217;ai retir&#233; le surplus d&amp;#8217;infos) :&lt;/p&gt;
&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;# signale que cette configuration est valable&lt;br&gt;# pour toutes les connections sur le port 80 (http)&lt;br&gt;# il est possible de specifier une adresse IP a la place de *&lt;br&gt;NameVirtualHost *:80&lt;br&gt;&lt;br&gt;&amp;lt;Virtualhost *:80&amp;gt;&lt;br&gt;    ServerName www.mon_site1.com       # nom du serveur&lt;br&gt;    DocumentRoot /var/www/site1        # la racine du site&lt;br&gt;    # regles du repertoire /var/www/site1&lt;br&gt;    &amp;lt;Directory /var/www/site1&amp;gt;&lt;br&gt;        Options Indexes&lt;br&gt;        AllowOverride FileInfo         # active les .htaccess&lt;br&gt;        Order allow,deny&lt;br&gt;        Allow from all&lt;br&gt;    &amp;lt;/Directory&amp;gt;&lt;br&gt;&lt;br&gt;    # dans le cas ou le serveur liste un repertoire,&lt;br&gt;    # la description du serveur n'est pas affichee&lt;br&gt;    ServerSignature Off&lt;br&gt;&amp;lt;/Virtualhost&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;Virtualhost *:80&amp;gt;&lt;br&gt;    ServerName www.mon_site2.com&lt;br&gt;    DocumentRoot /home/moi/www&lt;br&gt;    &amp;lt;Directory /home/moi/www&amp;gt;&lt;br&gt;        Options Indexes&lt;br&gt;        AllowOverride FileInfo&lt;br&gt;        Order allow,deny&lt;br&gt;        allow from all&lt;br&gt;    &amp;lt;/Directory&amp;gt;&lt;br&gt;    ServerSignature Off&lt;br&gt;&amp;lt;/Virtualhost&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;    </content>
  </entry>
</feed>

