Made in Sp4ce2012-05-25T10:53:54+02:00http://www.sp4ce.net/Baptiste Pernet Mugnierbapt@sp4ce.netString Error Detection In Javascript2012-05-18T00:00:00+02:00http://www.sp4ce.net/computer/2012/05/18/string-error-detection-in-javascript<h3>String comparison</h3>
<p>When you want to compare string in order to detect errors, it can get very complicated. You can use a simple function like this</p>
<div class="highlight"><pre><code class="javascript"><span class="kd">function</span> <span class="nx">compare</span><span class="p">(</span><span class="nx">string1</span><span class="p">,</span> <span class="nx">string2</span><span class="p">,</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">j</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// We are a the end of one of the string, return the differences of caracters (= numbers of errors).</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">string1</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="nx">i</span> <span class="o">||</span> <span class="nx">string2</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="nx">j</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">abs</span><span class="p">(</span><span class="nx">string1</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="nx">string2</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">string1</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">==</span> <span class="nx">string2</span><span class="p">[</span><span class="nx">j</span><span class="p">])</span> <span class="p">{</span>
<span class="c1">// The caracters are equal, we continue to the next caracters.</span>
<span class="nx">compare</span><span class="p">(</span><span class="nx">string1</span><span class="p">,</span> <span class="nx">string2</span><span class="p">,</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="c1">// We test BOTH insertion and deletion and return the least error weight.</span>
<span class="kd">var</span> <span class="nx">insertion</span> <span class="o">=</span> <span class="nx">compare</span><span class="p">(</span><span class="nx">string1</span><span class="p">,</span> <span class="nx">string2</span><span class="p">,</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">j</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">deletion</span> <span class="o">=</span> <span class="nx">compare</span><span class="p">(</span><span class="nx">string1</span><span class="p">,</span> <span class="nx">string2</span><span class="p">,</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">insertion</span><span class="p">,</span> <span class="nx">deletion</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>However this have a bad complexity because it will compare again part of the string that has been already compare in another path of the comparison. For example, if you compare ‘abcdefgh’ with ‘aabcdefgh’, you go into a deep recursion.</p>
<p>By using a backtracking algorithm, we can reduce the complicity to be polynomial.</p>
<h3>Backtracking matrix</h3>
<p>The main idea is to initialize the border of a matrix, because we know the value (the difference between the length), and then backtrack the values until the beginning of the strings.</p>
<table style="margin-left: 40px;">
<tbody>
<tr>
<td></td>
<td>h</td>
<td>e</td>
<td>l</td>
<td>l</td>
<td>o</td>
<td></td>
</tr>
<tr>
<td>h</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>4</td>
</tr>
<tr>
<td>l</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>3</td>
</tr>
<tr>
<td>l</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>2</td>
</tr>
<tr>
<td>o</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>1</td>
</tr>
<tr>
<td></td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>The backtrack is very easy, you use this function:</p>
<div class="highlight"><pre><code class="javascript"><span class="kd">function</span><span class="p">(</span><span class="nx">reference</span><span class="p">,</span> <span class="nx">input</span><span class="p">,</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">j</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">reference</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">==</span> <span class="nx">input</span><span class="p">[</span><span class="nx">j</span><span class="p">])</span>
<span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">][</span><span class="nx">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">];</span>
<span class="k">else</span> <span class="p">{</span>
<span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">][</span><span class="nx">j</span><span class="p">],</span> <span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>And if you want to remember the path you made thought the backtracking, the matrix value became an object and the backtracking function will be:</p>
<div class="highlight"><pre><code class="javascript"><span class="kd">function</span><span class="p">(</span><span class="nx">reference</span><span class="p">,</span> <span class="nx">input</span><span class="p">,</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">j</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">reference</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">==</span> <span class="nx">input</span><span class="p">[</span><span class="nx">j</span><span class="p">])</span>
<span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">][</span><span class="nx">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">].</span><span class="nx">value</span><span class="p">,</span>
<span class="nx">direction</span><span class="o">:</span> <span class="s1">'diagonal'</span>
<span class="p">};</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">][</span><span class="nx">j</span><span class="p">].</span><span class="nx">value</span> <span class="o"><</span> <span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">].</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
<span class="nx">direction</span><span class="o">:</span> <span class="s1">'down'</span>
<span class="p">};</span>
<span class="k">else</span> <span class="p">{</span>
<span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">value</span><span class="o">:</span> <span class="nx">matrix</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="nx">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
<span class="nx">direction</span><span class="o">:</span> <span class="s1">'right'</span>
<span class="p">};</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>And so the backtracking matrix becomes something that look like this. The path that shows the error is highlighted in red. It shows where it detects insertion or deletion.</p>
<table style="margin-left: 40px;">
<tbody>
<tr>
<td></td>
<td>h</td>
<td>e</td>
<td>l</td>
<td>l</td>
<td>o</td>
<td></td>
</tr>
<tr>
<td>h</td>
<td style="color: red; ">1</td>
<td>2</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>l</td>
<td>2</td>
<td style="color: red; ">1</td>
<td style="color: red; ">0</td>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>l</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td style="color: red; ">0</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>o</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td style="color: red; ">0</td>
<td>1</td>
</tr>
<tr>
<td></td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td style="color: red; ">0</td>
</tr>
</tbody>
</table>
<p>You can find the entire source code and examples on <a href="https://github.com/sp4ce/javascript-lcs">github</a>.<br />
You can play with the working code <a href="/lcs">here</a>.</p>
<p>This work was done with the help of <a href="http://www.linkedin.com/pub/jean-marie-larchev%C3%AAque/2/920/159">Jean-Marie Larchevêque</a>.</p>La Douleur, Mais Aussi Le Soulagement2012-04-02T00:00:00+02:00http://www.sp4ce.net/miscellaneous/2012/04/02/la-douleur,-mais-aussi-le-soulagement<p>La vitre se brisa. Il passa au travers. Pendant un bref instant, le sol se déroba sous ses pieds, il perdit pieds. Sa pensée fut d’un bloc focalisée sur un seul fait. Je suis perdu, je vais tomber dans un gouffre haut de dix étages, je vais mourrir. On lui avait dit qu’à ce moment-là il verrait sa vie entière défiler devant ses yeux, mais c’était faux, il n’avait rien vu. Il avait juste ressenti un immense désarroi, une grande peur et une résignation. Le fait de savoir que l’on va mourir dans les prochaines secondes. Malgré tout, les mains tentent désespérément de s’accrocher à un bout de vie, les jambes péparent une réception. Tous nos réflexes de survie se mobilisent pour tenter de parer à l’inévitable. Notre coprs refuse, hors de contrôle, ce que l’esprit espère, ou fatalement, passivement attend.</p>
<p>Et puis directement, ou presque, c’est le choc, beaucoup plus tôt que prévu. Et puis c’est le noir aussi. Ensuite tout s’enchaine à une telle vitesse que la peur et la surprise gènent l’esprit, l’empêche de réagir correctement. Et c’est encore une chute, un chavirement sur le coté, le sol est dur, le dos fait mal. Alors qu’il vient à peine de comprendre qu’il vient de passer au travers d’une fenêtre, il se retrouve étendu là par terre dans la cage d’escalier. Une chute de quatre mètres au lieu de dix étages. La douleur, mais aussi le soulagement.</p>Facebook Page: Automatic Answer2012-02-15T00:00:00+01:00http://www.sp4ce.net/computer/2012/02/15/facebook-page:-automatic-answer<h3>Facebook Page: Santa Claus</h3>
<p>Facebook page is a way to promote your business or someone. In the company I work, we decided to make a Santa Claus page that is in fact a bot that replies to user comments on the wall. It is really fun to see people interact with it, and we currently have 120 000 fan on the page. The page in the French, but please <a href="https://www.facebook.com/ParlerAuPereNoel">have a look</a>.</p>
<p>The architecture needs a fb connector that:</p>
<ul>
<li>polls the fb page</li>
<li>get the answer for the bot</li>
<li>post the answer to the corresponding conversation</li>
</ul>
<p>In this post, I give more details on how do a programatic post on a facebook page wall, answering a comment of a user.</p>
<h3>Posting Message</h3>
<p>Facebook has a fully <span class="caps">REST</span> <span class="caps">API</span> that is know as the open graph <span class="caps">API</span>. There are various library on the web to connect to it, using C#, JavaScript or php. Please visit the <a href="http://developers.facebook.com/docs/sdks/">facebook SDKs & tools page</a> to know more about that, and the <a href="http://developers.facebook.com/docs/reference/api/">graph <span class="caps">API</span> page</a> about the <span class="caps">API</span> itself.</p>
<p>Once you know that, have a look at</p>
<ul>
<li><a href="http://graph.facebook.com/167471789945400">http://graph.facebook.com/167471789945400</a>,</li>
<li><a href="http://graph.facebook.com/167471789945400/feed">http://graph.facebook.com/167471789945400/feed</a></li>
</ul>
<p>The first request is the publis Santa Claus page, it gives you general information about the page. However, the second gives you the stream of the page wall (<span class="caps">GET</span>) or allows you to post content to the wall (<span class="caps">POST</span>), then you should get this message:</p>
<div class="highlight"><pre><code class="javascript"> <span class="nx">error</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">message</span><span class="o">:</span> <span class="s2">"An access token is required to request this resource."</span><span class="p">,</span>
<span class="nx">type</span><span class="o">:</span> <span class="s2">"OAuthException"</span><span class="p">,</span>
<span class="nx">code</span><span class="o">:</span> <span class="mi">104</span>
<span class="p">}</span>
</code></pre>
</div>
<p>You need an <strong><code>access token</code></strong> to access the resource. If you want to know more about access token and OAuth 2.0 authentication and authorization, please do, but here, the only thing you need to know is that <code>access token</code> is the way to say to facebook: <em>hello, I am this guy and I have the right to do that and that</em>. Once you have the access token, Facebook trusts you.</p>
<h3>Access Token</h3>
<p>In order to get an access token for your page, you need an application key and of course a page. In order to create the application, go to <a href="http://www.facebook.com/developers/apps.php">My Applications</a> page and create one application. Now you need to setup a temporary site url in order to execute a small JavaScript code that will help you to get the <code>access token</code>.</p>
<p>You need:</p>
<ul>
<li>site url: http://www.sp4ce.net/facebook/access_token</li>
<li>domain name: sp4ce.net</li>
</ul>
<a href="/images/facebook_app_config.png" class="image_dialog" id="image_dialog3294180_link">
<img src="/images/facebook_app_config.min.png" alt="facebook_app_config"/>
<img src="/images/facebook_app_config.png" id="image_dialog3294180_image" alt="facebook_app_config"/>
</a>
<script type="text/javascript">
$(function() {
$('#image_dialog3294180_image').dialog({
autoOpen: false,
width: 1035 ,
modal: true,
});
});
$('#image_dialog3294180_link').click(function(e) {
e.preventDefault();
$('#image_dialog3294180_image').dialog('open');
});
</script>
<p>Then you can go to <a href="http://www.sp4ce.net/facebook/access_token">http://www.sp4ce.net/facebook/access_token</a>, enter the application id and click enter. You can check that the permission given if enought but it should be ok. You should be request to give some access to the applicatio you just created and after 1 second, you will see a table with the access token</p>
<p>Enjoy !</p>Importez Ses Contacts Google Dans Un Nokia C32012-01-23T00:00:00+01:00http://www.sp4ce.net/miscellaneous/2012/01/23/importez-ses-contacts-google-dans-un-nokia-c3<p>J’ai récemment changé d’opérateur téléphonique: je suis passé de Bouygues Télécom à Free Mobile. Depuis novembre 2011 jusqu’à la semaine dernière, de peur de me ré engager avec Bouygues, et en attendant les offres de Free, j’avais un Nokia 1616, qui est un des téléphones les plus simples du marché.</p>
<p>Après etre abonné chez Free, et constaté que le prix du téléphone que j’aurais aimé avoir (à savoir un android) dépassait largement le budget que j’alloue pour ce genre de choses, j’ai décidé de jeter un oeil sur les entrées de gamme. J’ai donc choisi le <a href="http://www.nokia.com/fr-fr/produits/mobiles/c3-00/">Nokia C3</a> après 10 minutes de réflexion (j’ai aussi un budget <em>temps de réflexion pour ce genre de choses</em> que je devrais d’ailleurs revoir à la hausse).</p>
<p>Toujours est-il que maintenant j’ai mon téléphone Nokia tout vide, sans aucun contact à l’intérieur. Le temps de pleurer sur les bienfaits de la synchronization avec son compte gmail, fonctionalité proposée par les androids, que me vient l’idée d’essayer d’importer mes contacts. Grâce à l’application <a href="http://www.nokia.com/fr-fr/support/telechargement/">Nokia Suite</a> je peux synchroniser mon téléphone avec un fichier de sauvegarde sur mon pc. Le fichier de sauvegarde se trouve dans <code>~\AppData\Local\Nokia\Nokia Data Store\DataBase\MDataStore.db3</code> et c’est une base de données SQLite. Un peu de <em>reverse engineering</em> dans leur base de données et j’ai accouché cet après midi d’un petit script <code>ruby</code> d’import depuis le fichier <span class="caps">CSV</span> que l’on peut facilement obtenir depuis l’interface web de Google.</p>
<p><code>import.rb</code></p>
<div class="highlight"><pre><code class="ruby"><span class="nb">require</span> <span class="s1">'csv'</span>
<span class="nb">require</span> <span class="s1">'rubygems'</span>
<span class="nb">require</span> <span class="s1">'sqlite3'</span>
<span class="nb">require</span> <span class="s1">'uuid'</span>
<span class="c1"># Parameters</span>
<span class="no">GOOGLE_EXPORT</span><span class="o">=</span><span class="s1">'google.csv'</span>
<span class="no">NOKIA_DATABASE</span><span class="o">=</span><span class="s1">'C:\Users\bpernetmugnier.VIRTUOZ\AppData\Local\Nokia\Nokia Data Store\DataBase\MDataStore.db3'</span>
<span class="c1"># Read the csv file and create a array of hash table</span>
<span class="n">csv_data</span> <span class="o">=</span> <span class="no">CSV</span><span class="o">.</span><span class="n">read</span> <span class="no">GOOGLE_EXPORT</span>
<span class="n">headers</span> <span class="o">=</span> <span class="n">csv_data</span><span class="o">.</span><span class="n">shift</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span><span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="n">i</span><span class="o">.</span><span class="n">to_s</span> <span class="p">}</span>
<span class="n">string_data</span> <span class="o">=</span> <span class="n">csv_data</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span><span class="o">|</span><span class="n">row</span><span class="o">|</span> <span class="n">row</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span><span class="o">|</span><span class="n">cell</span><span class="o">|</span> <span class="n">cell</span><span class="o">.</span><span class="n">to_s</span> <span class="p">}</span> <span class="p">}</span>
<span class="n">users</span> <span class="o">=</span> <span class="n">string_data</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span><span class="o">|</span><span class="n">row</span><span class="o">|</span> <span class="no">Hash</span><span class="o">[*</span><span class="n">headers</span><span class="o">.</span><span class="n">zip</span><span class="p">(</span><span class="n">row</span><span class="p">)</span><span class="o">.</span><span class="n">flatten</span><span class="o">]</span> <span class="p">}</span>
<span class="c1"># Create sqlite connection.</span>
<span class="n">database</span> <span class="o">=</span> <span class="no">SQLite3</span><span class="o">::</span><span class="no">Database</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">NOKIA_DATABASE</span><span class="p">)</span>
<span class="n">uuid_lib</span> <span class="o">=</span> <span class="no">UUID</span><span class="o">.</span><span class="n">new</span>
<span class="n">users</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">user</span><span class="o">|</span>
<span class="k">if</span> <span class="p">(</span><span class="n">user</span><span class="o">[</span><span class="s1">'Name'</span><span class="o">].</span><span class="n">start_with?</span> <span class="s1">'.'</span><span class="p">)</span>
<span class="k">next</span>
<span class="k">end</span>
<span class="n">rows</span> <span class="o">=</span> <span class="n">database</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">'SELECT * FROM Contact WHERE GivenName="%s" AND LastName="%s"'</span> <span class="o">%</span>
<span class="o">[</span><span class="n">user</span><span class="o">[</span><span class="s1">'Given Name'</span><span class="o">]</span><span class="p">,</span> <span class="n">user</span><span class="o">[</span><span class="s1">'Family Name'</span><span class="o">]]</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">rows</span><span class="o">.</span><span class="n">size</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">next</span>
<span class="k">end</span>
<span class="n">uuid</span> <span class="o">=</span> <span class="n">uuid_lib</span><span class="o">.</span><span class="n">generate</span>
<span class="n">database</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"INSERT INTO Contact (GUID, GivenName, LastName, GeneralMobile) VALUES ('{%s}', '%s', '%s', '%s');"</span> <span class="o">%</span> <span class="o">[</span><span class="n">uuid</span><span class="p">,</span> <span class="n">user</span><span class="o">[</span><span class="s1">'Given Name'</span><span class="o">]</span><span class="p">,</span> <span class="n">user</span><span class="o">[</span><span class="s1">'Family Name'</span><span class="o">]</span><span class="p">,</span> <span class="n">user</span><span class="o">[</span><span class="s1">'Phone 1 - Value'</span><span class="o">]]</span><span class="p">)</span>
<span class="n">database</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"INSERT INTO Contact_NOS (GUID, PreferredNumberId) VALUES ('{%s}', 1);"</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">database</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"INSERT INTO Item (GUID, CreationDate, LastModifiedDate, ImportDate, ItemType) VALUES ('{%s}', 40931.58788489, 40931.58788489, 40931.58788489, 'application/vnd.nokia.nos.contact');"</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Petite remarque concernant Google et Nokia, si le premier offre de nombreuses possibilités pour importer, exporter, merger ses contacts, le deuxième n’y a pas pensé. J’était trčè surpris de ne pas trouver, même une basique fonction “export” dans <em>Nokia Suite</em>. Est-ce un manque de temps ? d’investissement ? ou tout simplement d’idée ?</p>
<p>Et sinon, dans la base de données, les timestamp sont représentés sous un format de nombres réels qui m’est totalement inconnu. J’ai essayé de faire des soutraction, division, regression affine, etc. Mais je n’ai rien trouvé de très logique.</p>
<p>40931.58788489 == le 23 janvier 2012 à environ 15h06<br />
40931,6428253646 == le 23 janvier 2012 à environ 16h25</p>Macports Outdated Port Notification2012-01-22T00:00:00+01:00http://www.sp4ce.net/computer/2012/01/22/macports-outdated-port-notification<p>The <a href="http://www.macports.org/">MacPorts</a> Project is an open-source initiative for compiling, installing, and upgrading open-source software on Max OS X operating system. I’ve been using it for some years now and it is very stable and easy to use.</p>
<p>Yesterday afternoon, I wanted to finish the tag cloud plugin of my website when I run into a error in Jekyll. I fixed it, but I needed to upgrade MacPorts. I didn’t touch to it for months and I had a lot of outdated ports. It took me more than one hour to update everything and so delayed my work. I thought that I really needed to have notifications, or automatic update of ports.</p>
<p>I read at the <a href="https://trac.macports.org/wiki/UsingMacPortsQuickStart#HowdoIknowwhenanupdateisavailableDoIhavetoconstantlyperformmanualchecks">MacPorts Project documentation</a> and I found exactly what I needed in the <span class="caps">FAQ</span>: “How do I know when an update is available? Do I have to constantly perform manual checks?”.</p>
<p>Based on this, I created a small shell script:</p>
<p><code>update.sh</code></p>
<div class="highlight"><pre><code class="bash"><span class="c">#!/bin/sh</span>
<span class="c"># This script updates MacPorts and send you and email when there are ports to manually update.</span>
<span class="nv">MSMTP_DEST</span><span class="o">=</span>bapt at sp4ce.net
<span class="nv">MSMTP_CONFIG</span><span class="o">=</span>/Users/baptiste/.msmtprc
<span class="c"># This command "teaches" MacPorts about new updates.</span>
/opt/local/bin/port selfupdate
<span class="c"># Get the outdated ports</span>
<span class="nv">outdated</span><span class="o">=</span><span class="sb">`</span>/opt/local/bin/port outdated<span class="sb">`</span>
<span class="nb">echo</span> <span class="nv">$outdated</span> > /Users/baptiste/Scripts/MacPorts/outdated.txt
<span class="c"># mail the result</span>
<span class="c"># echo $outdated | msmtp -C $MSMTP_CONFIG $MSMTP_DEST</span>
</code></pre>
</div>
<p>I disable the mail command line because I finally didn’t want to receive email everyday, because if I can’t connect to my mac and perform the update, I will simply forget to do it. The best thing to do is to get the notification when I can really update the ports just after: when I open a terminal.</p>
<p>Then I put a line in my <code>.bashrc</code> file: <code>echo /Users/baptiste/Scripts/MacPorts/outdated.txt</code> and so I get a nice message in my terminal:</p>
<p><img src="/images/macports_no_outdated_port.png"/></p>
<p>Finally I setup a cron job as the root user (needed to run the selfupdate):</p>
<p><code>sudo crontab -e</code></p>
<p><code>* * * * * sh /Users/baptiste/Scripts/MacPorts/update.sh</code></p>Global Mutex In Ruby2011-02-21T00:00:00+01:00http://www.sp4ce.net/computer/2011/02/21/global-mutex-in-ruby.en<h3>Global Mutex</h3>
<p>In a multi thread environment, if you want to protect a critical section, you can use a semaphore. However in Ruby, this semaphore is only intantiated in your current process and cannot be shared among other ruby processes.</p>
<p>Imagine that you have a ruby code that is run by an external application. This code contains a critical section and you want to protect it.</p>
<p><code>chech.rb</code></p>
<div class="highlight"><pre><code class="ruby"><span class="nb">puts</span> <span class="s2">"take lock"</span>
<span class="c1"># to be defined</span>
<span class="nb">puts</span> <span class="s2">"begin critical section"</span>
<span class="nb">sleep</span> <span class="mi">2</span>
<span class="nb">puts</span> <span class="s2">"end critical section"</span>
<span class="nb">puts</span> <span class="s2">"release lock"</span>
</code></pre>
</div>
<p>Then to simulate the external application calls, we have a small batch script <code>loop.bat</code> that calls the Ruby code four times.</p>
<p><code>loop.bat</code></p>
<div class="highlight"><pre><code class="bat"><span class="k">for</span> <span class="n">/L</span> <span class="nv">%%i</span> in (<span class="m">0</span><span class="p">,</span> <span class="m">1</span><span class="p">,</span> <span class="m">3</span>) <span class="k">do</span> start ruby check.rb <span class="nv">%%i</span>
</code></pre>
</div>
<h3>File.flock method</h3>
<p>To solve this, the method <code>File.flock</code> allows you take an exclusive ressource on a file. So <code>check.rb</code> looks like:</p>
<p><code>chech.rb</code></p>
<div class="highlight"><pre><code class="ruby"><span class="nb">require</span> <span class="s1">'fileutils.rb'</span>
<span class="nb">require</span> <span class="s1">'tmpdir'</span>
<span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s2">"</span><span class="si">#{</span><span class="no">Dir</span><span class="o">.</span><span class="n">tmpdir</span><span class="si">}</span><span class="s2">/test.synchro"</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span>
<span class="nb">puts</span> <span class="s2">"take lock </span><span class="si">#{</span><span class="no">ARGV</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="si">}</span><span class="s2">"</span>
<span class="n">f</span><span class="o">.</span><span class="n">flock</span><span class="p">(</span><span class="no">File</span><span class="o">::</span><span class="no">LOCK_EX</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"sleep </span><span class="si">#{</span><span class="no">ARGV</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">sleep</span> <span class="mi">2</span>
<span class="nb">puts</span> <span class="s2">"end </span><span class="si">#{</span><span class="no">ARGV</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="si">}</span><span class="s2">"</span>
<span class="p">}</span>
<span class="nb">sleep</span> <span class="mi">60</span>
</code></pre>
</div>
<p>Then when you run <code>loop.bat</code> you have a global mutex, meaning that each process wait that every other process release the lock on the file <code>test.synchro</code>. The file is in the <code>TEMP</code> directory to be sure that you can have write access on this folder. It will be <code>/temp</code> on linux and <code>c:\users\CURRENT_USER\app_data\temp</code> on MS Windows. I didn’t try on my Mac, but I think that each call to <code>Dir.tmpdir</code> return the same folder.</p>
<h3>Demo</h3>
<p>Here a screenshot of when this short code runs (click to enlarge). You have to look closely to the timestamp of each action (specially the seconds) to understand what is happenning.</p>
<a href="/images/ruby_global_mutex.png" class="image_dialog" id="image_dialog12101790_link">
<img src="/images/ruby_global_mutex.min.png" alt="ruby_global_mutex"/>
<img src="/images/ruby_global_mutex.png" id="image_dialog12101790_image" alt="ruby_global_mutex"/>
</a>
<script type="text/javascript">
$(function() {
$('#image_dialog12101790_image').dialog({
autoOpen: false,
width: 840 ,
modal: true,
});
});
$('#image_dialog12101790_link').click(function(e) {
e.preventDefault();
$('#image_dialog12101790_image').dialog('open');
});
</script>
How To Have A Multilingual Website With Jekyll2011-01-15T00:00:00+01:00http://www.sp4ce.net/site/2011/01/15/how-to-have-a-multilingual-website-with-jekyll<h3>Languages</h3>
<p>The site is both in English and French. Jekyll doesn’t provide any support to have posts in two languages. It means that in your website meta data, the variable <code>site.posts</code> contains all your posts (both in English and French).</p>
<p>However, I wanted two versions of the home page, one version that contains only the English posts and the French only posts, and another version that contains only the French posts and the English only posts. So I am sure that every post is displayed, and available in the user favorite language. There is one home page called <code>index.en.html</code> and <code>index.fr.html</code>, both are laid out with <code>_layout/index.html</code> layout.</p>
<h3>Categories</h3>
<p>The site contains three categories of posts: <em>site</em> , <em>computer</em> and <em>miscellaneous</em> The <code>_layout/index.html</code> layout contains three widgets with the posts related to a category. Jekyll allows you to include part of pages in another using the <code>include</code> statemenent. So for a category (for example <em>computer</em>) it is:</p>
<div class="highlight"><pre><code class="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"panel"</span><span class="nt">></span>
<span class="nt"><h2></span>{{ page.computer_activities }}<span class="nt"></h2></span>
<span class="nt"><ul></span>
{% for post in site.categories.computer %}
{% include category.html %}
{% endfor %}
<span class="nt"></ul></span>
<span class="nt"></div></span>
</code></pre>
</div>
<p><code>page.computer_activities</code> contains the localized title of the category, specified in <code>index.fr.thml</code> (in French) and <code>index.en.html</code> (in English).<br />
<code>site.categories.computer</code> is a list of all the posts in the <em>computer</em> category.</p>
<p>Then the file <code>_includes/category.html</code> is very simple:</p>
<div class="highlight"><pre><code class="html">{% if post.multilingual != true %}
<span class="nt"><li></span>{% include post_link.html %}
{% if post.language == 'en' %}
{% include english_only.html %}
{% elsif post.language == 'fr' %}
{% include french_only.html %}
{% endif %}
<span class="nt"></p></li></span>
{% elsif post.language == page.language %}
<span class="nt"><li></span>{% include post_link.html %}<span class="nt"></p></li></span>
{% endif %}
</code></pre>
</div>
<p>So if it is not a multilingual post, I display it with a small flag that explain that it is a French only or English only post, else I display only the posts which have the same language as the page. (<code>_includes/post_link.html</code> is a small code that displays a post link, and open a <p> tag, for those who notified the closing </p>)</p>
<h3>Get the page language</h3>
<p>I choose these conventions:</p>
<ul>
<li>When a page is multilingual, it is named <code>page_name.language.textile</code> (<code>language</code> is <code>fr</code> or <code>en</code>)</li>
<li>When a page is only in one language, you don’t put the <code>language</code> extension, you set the language in the jekyll <code>yaml</code> header of the post.</li>
</ul>
<p>So, in both case, you know the language of a page, by looking at the url, if it is a multilingual post, or by looking at the post meta data. Then I extend the <code>Page</code> and <code>Post</code> class using ruby monkey patching in order to make this information available in the post and the page meta data in both case. For example, in the <code>_plugins/page.rb</code></p>
<div class="highlight"><pre><code class="ruby"><span class="nb">require</span> <span class="s1">'_plugins/get_language'</span>
<span class="k">module</span> <span class="nn">Jekyll</span>
<span class="k">class</span> <span class="nc">Page</span>
<span class="c1"># Return the data of the page with additional</span>
<span class="c1"># information if the page has a specific language.</span>
<span class="k">alias</span> <span class="n">orig_to_liquid</span> <span class="n">to_liquid</span>
<span class="k">def</span> <span class="nf">to_liquid</span>
<span class="c1"># Gather all the basic information of the page.</span>
<span class="nb">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">orig_to_liquid</span>
<span class="c1"># Get the language of the page from the name of the post</span>
<span class="n">language</span> <span class="o">=</span> <span class="no">GetLanguage</span><span class="o">.</span><span class="n">get_language</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">url</span><span class="p">)</span>
<span class="c1"># merge the language information with the page meta data.</span>
<span class="k">return</span> <span class="no">GetLanguage</span><span class="o">.</span><span class="n">merge_data</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">language</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
</div>
<p>The method <code>GetLanguage.merge_date</code> looks like:</p>
<div class="highlight"><pre><code class="ruby"><span class="c1"># Merge the data with the language values.</span>
<span class="k">def</span> <span class="nc">GetLanguage</span><span class="o">.</span><span class="nf">merge_data</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">language</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">language</span><span class="p">)</span>
<span class="n">title</span> <span class="o">=</span> <span class="n">data</span><span class="o">[</span><span class="s1">'title'</span><span class="o">]</span> <span class="o">!=</span> <span class="kp">nil</span> <span class="p">?</span> <span class="n">data</span><span class="o">[</span><span class="s1">'title'</span><span class="o">]</span> <span class="p">:</span> <span class="s1">''</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">deep_merge</span><span class="p">({</span>
<span class="s1">'language'</span> <span class="o">=></span> <span class="n">language</span><span class="p">,</span>
<span class="s1">'multilingual'</span> <span class="o">=></span> <span class="kp">true</span><span class="p">,</span>
<span class="c1"># remove the language extension of the title</span>
<span class="s1">'title'</span> <span class="o">=></span> <span class="n">title</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="s2">".</span><span class="si">#{</span><span class="n">language</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span><span class="s1">''</span><span class="p">),</span>
<span class="p">})</span>
<span class="k">end</span>
<span class="k">return</span> <span class="n">data</span>
<span class="k">end</span>
</code></pre>
</div>
<p>So now, I know the language of each page, available in <code>page.language</code> or <code>post.language</code>, and I know also if it is multilingual page or not. Then I can display the small french or english flag at the bottom left corner when another language is available for a post. I also create two rss feeds <code>atom.en.xml</code> and <code>atom.fr.xml</code></p>
<h3>Get user favorite language</h3>
<p>At the top level of the site, there is a small <code>index.php</code> page, that redirects the request to the correct <code>index.fr.html</code> or <code>index.en.html</code>. This is the only piece of php code I have on the site, because it was available on my hosting server, but you could do the same thing in JavaScript if you want. The goal is to get the user favorite language by reading this information in the browser.</p>
<div class="highlight"><pre><code class="php"><span class="cp"><?php</span>
<span class="c1">// Définir ici les langues disponibles</span>
<span class="nv">$lang_list</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s2">"fr"</span><span class="p">,</span><span class="s2">"en"</span><span class="p">);</span>
<span class="nv">$accept_lang</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s2">","</span><span class="p">,</span> <span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'HTTP_ACCEPT_LANGUAGE'</span><span class="p">]);</span>
<span class="nb">reset</span><span class="p">(</span><span class="nv">$accept_lang</span><span class="p">);</span>
<span class="k">while</span> <span class="p">(</span><span class="k">list</span><span class="p">(</span><span class="nv">$index</span><span class="p">,</span> <span class="nv">$language</span><span class="p">)</span> <span class="o">=</span> <span class="o">@</span><span class="nb">each</span><span class="p">(</span><span class="nv">$accept_lang</span><span class="p">))</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">eregi</span><span class="p">(</span> <span class="s2">"^(.+);q=([0-9.]*)$"</span><span class="p">,</span> <span class="nv">$language</span> <span class="p">,</span> <span class="nv">$part</span><span class="p">))</span> <span class="p">{</span>
<span class="nv">$accept_lang</span><span class="p">[</span><span class="nv">$index</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$part</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">.</span> <span class="s1">';'</span> <span class="o">.</span> <span class="nv">$part</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nv">$accept_lang</span><span class="p">[</span><span class="nv">$index</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'1.0;'</span> <span class="o">.</span> <span class="nv">$accept_lang</span><span class="p">[</span><span class="nv">$index</span><span class="p">];</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nb">arsort</span><span class="p">(</span><span class="nv">$accept_lang</span><span class="p">);</span> <span class="c1">//tri par ordre de préférence</span>
<span class="nb">reset</span><span class="p">(</span><span class="nv">$accept_lang</span><span class="p">);</span>
<span class="k">while</span> <span class="p">(</span><span class="k">list</span><span class="p">(</span> <span class="p">,</span> <span class="nv">$a_lang</span><span class="p">)</span> <span class="o">=</span> <span class="o">@</span><span class="nb">each</span><span class="p">(</span><span class="nv">$accept_lang</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
<span class="nb">reset</span><span class="p">(</span><span class="nv">$lang_list</span><span class="p">);</span>
<span class="k">while</span> <span class="p">(</span> <span class="k">list</span><span class="p">(</span> <span class="p">,</span> <span class="nv">$language</span><span class="p">)</span> <span class="o">=</span> <span class="o">@</span><span class="nb">each</span><span class="p">(</span><span class="nv">$lang_list</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">strpos</span><span class="p">(</span><span class="nv">$a_lang</span><span class="p">,</span><span class="nv">$language</span><span class="p">)</span><span class="o">!=</span><span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$selected_language</span> <span class="o">=</span> <span class="nv">$language</span><span class="p">;</span>
<span class="k">break</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nb">unset</span><span class="p">(</span><span class="nv">$accept_lang</span><span class="p">,</span> <span class="nv">$a_lang</span><span class="p">,</span> <span class="nv">$language</span><span class="p">);</span>
<span class="c1">// langague par default (english)</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$selected_language</span><span class="p">))</span> <span class="p">{</span>
<span class="nv">$selected_language</span> <span class="o">=</span> <span class="s1">'en'</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?></span><span class="x"></span>
<span class="x"><html></span>
<span class="x"><head></span>
<span class="x"><meta http-equiv="Refresh" content="0; url=/index.</span><span class="cp"><?php</span> <span class="k">echo</span> <span class="nv">$selected_language</span> <span class="cp">?></span><span class="x">.html" /></span>
<span class="x"></head></span>
<span class="x"><body></span>
<span class="x"></body></span>
<span class="x"></html></span>
</code></pre>
</div>
<p>I get this code from my old web site and I don’t remember if it really comes out of my mind. I am definitly not a php guru, so please be kind with my skills :p I am open to any improvement you may suggest.</p>How To Use Watin With Nunit2011-01-06T00:00:00+01:00http://www.sp4ce.net/computer/2011/01/06/how-to-use-WatiN-with-NUnit.en<h3>WatiN Framework</h3>
<p>I was asked to write web tests for a suite of web applications. We already had a good coverage (about 65 %) with lots of unit tests on the controllers and models of our applications but it was hard to test the views.</p>
<p>Lots of functionalities are coded in <span class="caps">HTML</span>, <span class="caps">CSS</span> and Javascript and are not testable directly using back-end code. They require a specific runtime environment: the browser. The browser that reads the <span class="caps">HTML</span> and <span class="caps">CSS</span>, and runs the JavaScript.</p>
<p><a href="http://watin.sourceforge.net/">WatiN</a> (<em>pronounced as What-in</em>) is a framework that lets you run a browser and directly send intructions to it. You can visit pages, click different links and test content.</p>
<h3>NUnit Framework</h3>
<p>NUnit is a library in .Net to write and easily maintain unit tests in C#. If you use combine the use of WatiN and NUnit, you can write unit tests for you web application.</p>
<div class="highlight"><pre><code class="csharp"><span class="na">[Test, Category("WEB")]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">SearchForWatiNOnGoogle</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">using</span> <span class="p">(</span><span class="n">var</span> <span class="n">browser</span> <span class="p">=</span> <span class="k">new</span> <span class="n">IE</span><span class="p">(</span><span class="s">"http://www.google.com"</span><span class="p">))</span>
<span class="p">{</span>
<span class="n">browser</span><span class="p">.</span><span class="n">TextField</span><span class="p">(</span><span class="n">Find</span><span class="p">.</span><span class="n">ByName</span><span class="p">(</span><span class="s">"q"</span><span class="p">)).</span><span class="n">TypeText</span><span class="p">(</span><span class="s">"WatiN"</span><span class="p">);</span>
<span class="n">browser</span><span class="p">.</span><span class="n">Button</span><span class="p">(</span><span class="n">Find</span><span class="p">.</span><span class="n">ByName</span><span class="p">(</span><span class="s">"btnG"</span><span class="p">)).</span><span class="n">Click</span><span class="p">();</span>
<span class="n">Assert</span><span class="p">.</span><span class="n">IsTrue</span><span class="p">(</span><span class="n">browser</span><span class="p">.</span><span class="n">ContainsText</span><span class="p">(</span><span class="s">"WatiN"</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<h3>Extend WatiN to <span class="caps">CSS</span> selector with jQuery</h3>
<p>WatiN is great, but you cannot use <span class="caps">CSS</span> selector (cf. above example on how to find an element). in JavaScript frameworks (like <code>jQuery</code>), you can use <span class="caps">CSS</span> selectors to get an element. WatiN allows you to inject JavaScript in the browser.</p>
<div class="highlight"><pre><code class="csharp"><span class="n">using</span><span class="p">(</span><span class="n">var</span> <span class="n">browser</span> <span class="p">=</span> <span class="k">new</span> <span class="n">IE</span><span class="p">(</span><span class="s">"http://www.google.com"</span><span class="p">))</span>
<span class="p">{</span>
<span class="n">browser</span><span class="p">.</span><span class="n">Eval</span><span class="p">(</span><span class="s">"alert('Hello World!');"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre>
</div>
<p>So you can inject a <span class="caps">CSS</span> search monitor which will perform the search using <code>jQuery</code>, check if the element has an <code>id</code> attribute, set one if not and return this <code>id</code>. Then WatiN uses this <code>id</code> to get the element.</p>
<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">CssSearchMonitor</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">uniqueId</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">getElementId</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">selector</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="s2">"_no_element_"</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">$</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">elements</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">selector</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">elements</span><span class="p">.</span><span class="nx">length</span> <span class="o"><</span> <span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">element</span> <span class="o">=</span> <span class="nx">elements</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">index</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">element</span><span class="p">.</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">result</span> <span class="o">=</span> <span class="nx">element</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">result</span> <span class="o">=</span> <span class="s2">"watin_search_"</span> <span class="o">+</span> <span class="nx">uniqueId</span><span class="o">++</span><span class="p">;</span>
<span class="nx">element</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">result</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="p">{</span> <span class="nx">getElementId</span><span class="o">:</span> <span class="nx">getElementId</span> <span class="p">};</span>
<span class="p">}</span> <span class="p">(</span><span class="nx">jQuery</span><span class="p">);</span>
</code></pre>
</div>
<p>And then on the WatiN side, you inject the JavaScript and you call <code>CssSearchMonitor.getElementId</code> in order to get an element id.</p>
<div class="highlight"><pre><code class="csharp"><span class="kt">string</span> <span class="n">javascript</span> <span class="p">=</span> <span class="n">getJavaScript</span><span class="p">();</span> <span class="c1">// Get the javascript of the css search monitor.</span>
<span class="n">using</span><span class="p">(</span><span class="n">var</span> <span class="n">browser</span> <span class="p">=</span> <span class="k">new</span> <span class="n">IE</span><span class="p">(</span><span class="s">"http://www.google.com"</span><span class="p">))</span>
<span class="p">{</span>
<span class="n">browser</span><span class="p">.</span><span class="n">Eval</span><span class="p">(</span><span class="n">javascript</span><span class="p">);</span>
<span class="kt">string</span> <span class="n">id</span> <span class="p">=</span> <span class="n">browser</span><span class="p">.</span><span class="n">Eval</span><span class="p">(</span><span class="s">"CssSearchMonitor.getElementId('div.myClass input[input=\"button\"]', 1)"</span><span class="p">);</span>
<span class="n">Button</span> <span class="n">button</span> <span class="p">=</span> <span class="n">browser</span><span class="p">.</span><span class="n">Button</span><span class="p">(</span><span class="n">id</span><span class="p">);</span>
<span class="n">button</span><span class="p">.</span><span class="n">Click</span><span class="p">();</span>
<span class="p">}</span>
</code></pre>
</div>
<p>In order to use it intensively, you still need to refactor it to make it easy to use, but the main idea is here. Happy testing with WatiN and NUnit.</p>
<p>But there is still an open problem, how do you measure the coverage of the web application ?</p>
<h3>Links</h3>
<p><a href="http://spin.atomicobject.com/2010/11/11/fast-er-css-selector-based-element-lookups-in-watin-via-jquery">Fast(er) <span class="caps">CSS</span> Selector Based Element lookups in Watin via jQuery</a></p>
<p><a href="http://stackoverflow.com/questions/2375709/how-to-wait-for-jquery-ajax-requests-to-complete-from-watin">How to wait for jQuery Ajax requests to complete from WatiN?</a></p>Jekyll Migration2010-12-29T00:00:00+01:00http://www.sp4ce.net/site/2010/12/29/Jekyll-Migration<h3>Static <span class="caps">HTML</span></h3>
<p>My website is entirely done in static <span class="caps">HTML</span>. There is no dynamic rendering on the server side and every page is shown as it is. I think dynamic pages are cool but not really a requirement in most of case. The site is a blog and you don’t need a database behind it to store each article and a web engine that displays them.</p>
<p>A blog post is only content that is decorated with some <span class="caps">HTML</span>/<span class="caps">CSS</span> to make it nice. However this <span class="caps">HTML</span> won’t change (except if I decide it), so once you generate your blog post, you don’t have to do it again. That is how static web generator works, they create every page that exists on the site using specific layouts. If you compare it to a dynamic blog, you realize that the blog generates a page every time you visit it !</p>
<h3>Jekyll</h3>
<p>Jekyll is a blog aware static web generator. It is done in Ruby so you can easily (cf. monkey patching for example) extend the behavior or add a new feature. It uses Markdown or Textile format for blog posts and Liquid converters. This is also the engine behind GitHub Pages, which you can use to host your project’s page or blog.</p>
<p>When you run <code>jekyll</code> command, it goes thought your template directory and generate the html of the site.</p>
<h3>Template directory</h3>
<pre>
|-- _config.yml
|-- _includes
|-- category.html
`-- post_link.html
|-- _layouts
|-- default.html
|-- index.html
|-- post.html
`-- under_construction.html
|-- _plugins
|-- get_language.rb
|-- page.rb
`-- post.rb
|-- _site
|-- computer
|-- _drafts
`-- _posts
|-- miscellaneous
|-- _drafts
`-- _posts
|-- site
|-- _drafts
`-- _posts
|-- css
|-- data
|-- images
|-- index.en.html
|-- index.fr.html
`-- index.html
</pre>
<p>The website is generated in the <code>_site</code> folder. I use three categories of posts: <code>computer</code>, <code>site</code> and <code>miscellaneous</code>. In the index page I display the lastest posts of each category in 3 panels. <code>index.html</code> redirects the request to <code>index.en.html</code> which is the English version of the index.</p>
<h3>Comming soon</h3>
<p>I will post another article on how language is handled on the site. Also I will add the possibility to use twitter to leave reaction on each article.</p>Paris Old Quaries Network2010-03-22T00:00:00+01:00http://www.sp4ce.net/miscellaneous/2010/03/22/paris-old-quaries-network.enJosso Csharp Agent2009-09-14T00:00:00+02:00http://www.sp4ce.net/computer/2009/09/14/josso-csharp-agent.en<h3>What is <span class="caps">JOSSO</span> ?</h3>
<p><span class="caps">JOSSO</span> is a <a href="http://en.wikipedia.org/wiki/Single_sign-on"><span class="caps">SSO</span></a> system (Single Sign-On). It is an open source J2EE infrastructure aimed to provide a solution for centralized, platform neutral, user authentication and authorization.</p>
<p><span class="caps">JOSSO</span> runs on various J2EE servers: Apache Tomcat, JBoss application server, WebLogic application server, Apache Geronimo, etc. The client part has been also ported on various environement such as <span class="caps">IIS</span>, Apache (Ruby, Python, Perl) and <span class="caps">PHP</span> in order to allow a large <span class="caps">SSO</span> system over multiple applications.</p>
<p>For futher information on the system, how to install it, its possibilities, please visit <a href="http://www.josso.org">josso.org</a>.</p>
<h3><span class="caps">ASP</span>.Net Client</h3>
<p>Now you have been through the Josso website, that you have installed it, have tested and approved it, you may have noticed that the proposed client for mircrosoft is in <span class="caps">ASP</span>. Nowadays, many applications are using the framework .Net in companies. I took the liberty to write a simple agent in .Net</p>
<p>To download the solution (VS 2008, framework 3.5)</p>
<p><a href="/data/josso-agent-asp_net.zip"><span class="caps">JOSSO</span> (~ 20 Ko)(format zip)</a></p>
<p>To make it run, you need to register the ActiveX <span class="caps">JOSSO</span> client of the version 1.8.1 of Josso. To do it, download <a href="https://josso.svn.sourceforge.net/svnroot/josso/josso1/branches/JOSSO_1_8_1_B/josso/distributions/josso/src/main/resources/dist/agents/bin/">JossoActiveX.dll</a> and follow <a href="http://www.josso.org/confluence/display/JOSSO1/Setup+JOSSO+Agent+-+ASP">the instructions</a> on the josso.org site.</p>
<p>Then, use the web.config file of the project Josso.Agent.Test to configure your client.</p>Vivre Six Mois Au Japon2008-02-08T00:00:00+01:00http://www.sp4ce.net/miscellaneous/2008/02/08/vivre-six-mois-au-japon<h3>Mon Stage</h3>
<p>Commençons par ce qui m’a pris le plus de mon temps. J’ai fais mon stage à <a href="http://www.atr.jp"><span class="caps">ATR</span></a>, un labo de recherche en télécommunications. Le sujet de mon stage était la reconnaissance de comportements humains aux alentours du robot pour aider celui-ci à interargir de façon correcte avec les humains.</p>
<p>C’était très stimulant de travailler au sein d’une équipe de chercheur de haut niveau. Au début je pensais faire de la robotique, mais en fait j’ai fais de l’intelligence artifielle codée en Java. je travaillais sur des données que je devais recupérer sur un serveur, traiter, et mettre à disposition sur un autre serveur pour que le robot s’y connecte.</p>
<p>En plus, il n’y avait pas trop de pressions et une assez grande marge de manoeuvre pour les idées personnelles. J’ai vraiment profité de ça pour mettre en avant ma façon de voir les interactions. Mon seul regret est d’avoir codé une application off-line et d’avoir très peu utilisé le robot.</p>
<p>Bon passons maintenant aux choses serieuses :p</p>
<h3>La Vie Japonnaise</h3>
<p>La vie était plutot douce où j’habitais, dans la campagne japonnaise entre Kyoto (京都) et Nara (奈良). J’habitais à <a href="http://maps.google.com/maps?f=q&source=s_q&hl=fr&geocode=&q=Takanohara+Station,+Japan&sll=39.520992,140.537109&sspn=8.065831,20.983887&ie=UTF8&hq=&hnear=Takanohara+Station,+Japon&ll=34.742741,135.688705&spn=0.268573,0.655746&t=h&z=11">Takanohara (高の原)</a>, c’est une petite ville assez tranquille avec son centre commerciale, sa banque, sa gare et ses danchis (quartiers résidentiels).</p>
<p>En dehors de mon travail, le week end, j’essayais de m’amuser autant que possible et de rencontrer de nouveaux amis. À mon arrivé je suis beaucoup sorti avec un américain prénommé de Ben qui venait du <span class="caps">MIT</span>. Mais ensuite, j’ai commencé a connaitre quelques Japonnais, et à avoir des amis. C’était vraiment une expérience de re-commencer une vie là-bas, se refaire des amis, etc.</p>
<h3>Les Japonnais</h3>
<p>À cause de la langue, c’est pas forcément facile de se faire des rencontres… le japonnais, c’est quand même très dur et j’ai jamais été fort en langue. Cependant les japonnais sont dans l’ensemble très très gentils. S’ils décident de vous aider dans la rue, vous êtes sûres qu’ils ne vous laisseront pas tant que vous ne saurez pas votre route. Je ne compte plus le nombre de fois où j’ai été accompagné par un japonnais jusqu’à l’endroit où je voulais aller même si ça lui faisait faire un détour !</p>
<p>Cependant, derrière cette gentillesse, se cache une certaine froideur et une distance infranchissable. Lorsque vous êtes au Japon, vous êtes un Gaijin (外人 litt. personne de l’exterieure) et vous le sentez. Ce n’est pas du racisme, attention, c’est juste que pour un japonnais, toutes choses doivent être à leurs places et votre place, c’est celle du Gaijin.</p>
<h3>Liens</h3>
<p><a href="http://jpoptrash.nihon-fr.com/">JPop Trash</a>, un site troisième degrée sur la culture japonnaise.</p>Irc Server With Erlang Language2007-10-04T00:00:00+02:00http://www.sp4ce.net/computer/2007/10/04/irc-server-with-erlang-language.en<h3>Erlang</h3>
<p>Erlang is not a very common language, but very useful. I invite you to read <a href="http://en.wikipedia.org/wiki/Erlang_(programming_language)">wikipedia</a> to learn more about it. From my point of view, I liked Erlang for two reasons. First of all, it is similar to CamL, a language I like because it uses a match-case paradigm. And secondly, <span class="caps">THE</span> point of Erlang is that you can update your code, and then apply the change without restarting the module you are running !</p>
<p>This capacity is adapted to <span class="caps">IRC</span>, because if you have clents (users) connected on your server and you need to update it, you can do it whitout restarting it, so any user will be disconnected. This make the server very stable across updates.</p>
<h3><span class="caps">IRC</span></h3>
<p>Internet Relay Chat allow you to talk with other users using a channel system. Channel can be described as meeting rooms. Users can discuss in the same time. <span class="caps">IRC</span> is an old protocol and it is fully specified by the last rfc which is <a href="http://www.irchelp.org/irchelp/rfc/rfc2813.txt">rfc2813</a>. I tried to follow as much as possible this rfc, but my server is very simple.</p>
<h3>Links</h3>
<p><a href="/data/server_irc_erlang.tar">Project’s sources</a></p>
<p><a href="/data/server_irc_erlang.pdf">Project s slides</a> <img src="/images/icons/fr_20x14.gif" alt="Version Française" title="Version Française" /> (Français uniquement)</p>
<p><a href="http://www.irchelp.org/irchelp/rfc/">Details on <span class="caps">IRC</span> rfc</a></p>Student Mailpromo2007-09-18T00:00:00+02:00http://www.sp4ce.net/computer/2007/09/18/student-mailpromo.en<h3>Version 2.0 ??</h3>
<p>The version 1.0, then 1.1 was the first interface used for the very beginning of the project. It was not user friendly: it used a specific texte format and you couldn’t preview your message before you send them. Also each message was saved in a file on the server side.</p>
<p>The version 2.0 use a MySQL database to save, organize, edit recipients and edit messages. Every Monday of each week, a new empty message is created automatically.</p>
<h3>Screen shot</h3>
<p>The dashboard where you choose which message you want to take action upon it.<br />
<img src="/images/mailpromo/accueil.png" alt="dashboard" class="screenshot" /></p>
<p>The edition interface of each message, with the choice of recipient and preview before sending.<br />
<img src="/images/mailpromo/edition.png" alt="edit" class="screenshot" /></p>Playing With 3d And Catmull And Clark Algorithm2005-11-27T00:00:00+01:00http://www.sp4ce.net/computer/2005/11/27/playing-with-3D-and-Catmull-and-Clark-algorithm.en<h3>Some Pictures</h3>
<p><img src="/images/cattmull_clark.png" alt="3D surfaces" /></p>
<p>The software input some points (on the left) and with an algorithm (Catmull and Clark), it draws the surface (on the right).</p>
<h3>Source Code</h3>
<p>The source code of the software is only a few commented and the application is not so intuitive. If you have any questions, contact me.</p>
<p><a href='/data/catmull_clark.tar.gz'>Download</a></p>