Damien Lecan
Zola
2022-07-01T00:00:00+00:00
https://dlecan.com/atom.xml
How to replace Firefox Snap by classical Firefox deb package on Ubuntu 22.04?
2022-07-01T00:00:00+00:00
2022-07-01T00:00:00+00:00
https://dlecan.com/blog/how-to-replace-firefox-snap-classical-firefox-deb-package-ubuntu-22-04/
<p>With Ubuntu 22.04, Canonical started to ship Firefox packaged as a Snap instead of a Deb.</p>
<p>Here are the explanations to replace the Firefox Snap package by the classical deb package provided by the Mozilla team on Ubuntu 22.04.</p>
<span id="continue-reading"></span><h2 id="uninstall-permanently-the-transitional-firefox-deb-package">Uninstall permanently the transitional Firefox deb package</h2>
<p>This package replace the Firefox deb package and install the Snap package.
You don't need it anymore.</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>sudo apt remove firefox
</span></code></pre>
<p>If you don't remove it, the dev Firefox package you will install later will be overridden again and again by this one.</p>
<h2 id="copy-your-firefox-snap-profile">Copy your Firefox snap profile</h2>
<p>Your Firefox profile is located <strong>inside</strong> the snap install location.
So you have to move it to use it with the new Firefox installation.</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>cp -R ~/snap/firefox/.mozilla ~/
</span></code></pre>
<h2 id="install-permanently-the-deb-package-of-firefox">Install permanently the deb package of Firefox</h2>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>sudo add-apt-repository ppa:mozillateam/ppa
</span><span>sudo apt install -t 'o=LP-PPA-mozillateam' firefox
</span></code></pre>
<p>Then, create this new file:</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>sudo nano /etc/apt/preferences.d/firefox
</span></code></pre>
<p>Add the following content:</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>Package: firefox*
</span><span>Pin: release o=LP-PPA-mozillateam
</span><span>Pin-Priority: 1000
</span></code></pre>
<p>This file will prevent Ubuntu from restoring the transitional Firefox package.</p>
<h2 id="run-firefox">Run Firefox</h2>
<p>Run Firefox and choose your legacy profile:</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>firefox --profileManager
</span></code></pre>
<p>You just new to run this command once.</p>
<h2 id="remove-the-snap">Remove the snap</h2>
<p>Finally, you can remove the Firefox snap package:</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>sudo snap remove firefox
</span></code></pre>
Les cryptomonnaies sont-elles si polluantes ?
2022-02-01T00:00:00+00:00
2022-02-01T00:00:00+00:00
https://dlecan.com/blog/cryptomonnaies-sont-elles-si-polluantes/
<p>C'était ma deuxième participation à une conférence dans le cadre de la <a rel="noopener" target="_blank" href="https://nantesdigitalweek.com/">Nantes Digital Week 2021</a>, intitulée "Les cryptomonnaies sont-elles si polluantes ?", animée avec mon co-<code>[llègue (ex) | fondateur b&s | développeur b&s | mpère 😜]</code> <a rel="noopener" target="_blank" href="https://twitter.com/GuiillaumeN">Guillaume Nicolas</a>, chez SII Atlantique.</p>
<span id="continue-reading"></span>
<p>Dans cette conférence, nous avons :</p>
<ul>
<li>fait le point sur la consommation énergétique des Blockchains : Bitcoin, Ethereum, mais aussi d'autres</li>
<li>comparé avec d'autres secteurs, notamment avec la vidéo à la demande (Netflix ...)</li>
<li>apporté du recul sur le sujet, de la manière la plus neutre possible</li>
</ul>
<p>Nous avons même invité le célèbre mineur de Bitcoin <a rel="noopener" target="_blank" href="https://www.linkedin.com/in/s%C3%A9bastien-gouspillou-7663b7aa">Sébastien Gouspillou</a> à donner son avis sur le sujet en fin de conférence.</p>
<p>Le pitch :</p>
<blockquote>
<p>Après une introduction à la blockchain, à ses usages tels que les cryptomonnaies et autres « assets » numériques comme les NFT ou les Smart Contracts, nous présenterons l’envers du décor qui est à l’origine de son image de système polluant.</p>
<p>Ce sera l’occasion de faire le point sur la consommation énergétique du Bitcoin, et des blockchains en général, comparé à d’autres systèmes informatiques.</p>
<p>Mais nous verrons aussi qu’une nouvelle génération de blockchains est en cours de déploiement avec des principes de fonctionnement beaucoup plus vertueux que l’on pourrait même qualifier de « sobres en énergie ».</p>
<p>Enfin, nous finirons sur les perspectives que la blockchain pourra apporter et ses compromis énergiques au regard de ses usages croissants.</p>
</blockquote>
<h2 id="quelques-photos-et-reactions">Quelques photos et réactions</h2>
<blockquote class="twitter-tweet"><p lang="fr" dir="ltr">C'est en train de commencer! 'Les cryptomonnaies sont-elles si polluantes ?' Meetup En direct aussi et en personne 😎🏁 <a href="https://twitter.com/dlecan?ref_src=twsrc%5Etfw">@dlecan</a> et <a href="https://twitter.com/GuiillaumeN?ref_src=twsrc%5Etfw">@GuiillaumeN</a> avec <a href="https://twitter.com/SebGouspillou?ref_src=twsrc%5Etfw">@SebGouspillou</a> dans le cadre de la <a href="https://twitter.com/hashtag/NantesDigitalW?src=hash&ref_src=twsrc%5Etfw">#NantesDigitalW</a> dans les très beaux locaux de <a href="https://twitter.com/SII_Atlantique?ref_src=twsrc%5Etfw">@SII_atlantique</a> <a href="https://t.co/Gp94OaZ1HG">pic.twitter.com/Gp94OaZ1HG</a></p>— Blockchain et Société (@Blockchain44) <a href="https://twitter.com/Blockchain44/status/1440356773844578315?ref_src=twsrc%5Etfw">September 21, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="fr" dir="ltr">Pourquoi les cryptomonnaies sont-elles si polluantes ? <a href="https://twitter.com/dlecan?ref_src=twsrc%5Etfw">@dlecan</a> et <a href="https://twitter.com/GuiillaumeN?ref_src=twsrc%5Etfw">@GuiillaumeN</a> avec <a href="https://twitter.com/SebGouspillou?ref_src=twsrc%5Etfw">@SebGouspillou</a> dans le cadre de la <a href="https://twitter.com/hashtag/NantesDigitalW?src=hash&ref_src=twsrc%5Etfw">#NantesDigitalW</a> dans les beaux locaux de <a href="https://twitter.com/SII_Atlantique?ref_src=twsrc%5Etfw">@SII_atlantique</a> vont tout nous dire <a href="https://t.co/4s7iLwEOB1">pic.twitter.com/4s7iLwEOB1</a></p>— Nantes Digital Week (@NantesDigitalW) <a href="https://twitter.com/NantesDigitalW/status/1440359253215043587?ref_src=twsrc%5Etfw">September 21, 2021</a></blockquote>
<h2 id="les-slides">Les slides</h2>
<figure class="image is-16by9">
<iframe class="has-ratio" src="https://docs.google.com/presentation/d/e/2PACX-1vTVTPUs-Jx-yPDInMWu2l2VcSj888OzPVz-nRAlFm42i4YdUqlLLgZ4zd_ThXYZ-0nr8LRuEzlTtWBl/embed?start=false&loop=false&delayms=60000" frameborder="0" width="560" height="349" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</figure>
<h2 id="sii-atlantique-et-l-apero">SII Atlantique et l'apéro</h2>
<p>Un grand merci à SII Atlantique pour son accueil, leurs locaux sont très lumineux et la salle de conférence bien bien sonorisée.
Malheureusement, pas manque de temps, nous n'avons pas pu filmer la conférence.</p>
<p>Cela dit, pour les présents 😄, cela a été largement compensé par un apéro en fin de conférence, offert par SII Atlantique 🙏
C'était notre premier depuis septembre 2020, donc depuis un an.
Ça nous manquait 😛</p>
<p>La terrasse a été très appréciable et largement plébiscitée.
Je viendrai.</p>
<blockquote class="twitter-tweet"><p lang="fr" dir="ltr">Coucher de soleil chez <a href="https://twitter.com/SII_Atlantique?ref_src=twsrc%5Etfw">@SII_Atlantique</a> pour le meetup <a href="https://twitter.com/Blockchain44?ref_src=twsrc%5Etfw">@blockchain44</a> avec <a href="https://twitter.com/GuiillaumeN?ref_src=twsrc%5Etfw">@GuiillaumeN</a> <a href="https://twitter.com/dlecan?ref_src=twsrc%5Etfw">@Dlecan</a> et <a href="https://twitter.com/SebGouspillou?ref_src=twsrc%5Etfw">@SebGouspillou</a> sur la question “les cryptomonnaies sont-elles si polluantes?” <a href="https://twitter.com/NantesDigitalW?ref_src=twsrc%5Etfw">@NantesDigitalW</a> <a href="https://t.co/dc6tOQNGTY">pic.twitter.com/dc6tOQNGTY</a></p>— laure merlin (@lauremerlin) <a href="https://twitter.com/lauremerlin/status/1440383930037768197?ref_src=twsrc%5Etfw">September 21, 2021</a></blockquote>
Blockchain : code is law ?
2020-09-20T00:00:00+00:00
2020-09-20T00:00:00+00:00
https://dlecan.com/blog/blockchain-code-is-law/
<p>Pour la première fois, j'ai participé à une table ronde dans le cadre de la Nantes Digital Week 2020, intitulée "Blockchain : code is law?".</p>
<p>Nous avons discuté <em>blockchain</em>, <em>smart-contracts</em> ... d'un point de vue juridique.</p>
<span id="continue-reading"></span>
<p>Co-organisée par le <a rel="noopener" target="_blank" href="https://twitter.com/cablockchain">CAB Nantes</a>, le Barreau de Nantes et l'association Blockchain et Société, nous étions quatre à débattre le 17 septembre 2020, à la Maison de l'Avocat à Nantes :</p>
<ul>
<li>Julie BADER, avocate au <a rel="noopener" target="_blank" href="https://www.barreaunantes.fr/">barreau de Nantes</a></li>
<li>Delphine GANOOTE MARY, avocate au <a rel="noopener" target="_blank" href="https://www.barreaunantes.fr/">barreau de Nantes</a></li>
<li>Romain MENÉTRIER – CEO <a rel="noopener" target="_blank" href="https://www.emblock.co/">Emblock</a></li>
<li>Damien LECAN – CTO <a rel="noopener" target="_blank" href="https://unikname.com">Unikname</a> et Président de <a rel="noopener" target="_blank" href="https://blockchainsociete.org">Blockchain & Société</a></li>
</ul>
<blockquote class="twitter-tweet"><p lang="fr" dir="ltr">Passionnants échanges à la Maison de l'Avocat lors de la <a href="https://twitter.com/hashtag/NantesDigitalWeek?src=hash&ref_src=twsrc%5Etfw">#NantesDigitalWeek</a> sur les aspects juridiques de la <a href="https://twitter.com/hashtag/blockchain?src=hash&ref_src=twsrc%5Etfw">#blockchain</a> (Code is law): gouvernance et blockchain, protection des données à caractère personnel, avec <a href="https://twitter.com/Blockchain44?ref_src=twsrc%5Etfw">@Blockchain44</a>, <a href="https://twitter.com/cablockchain?ref_src=twsrc%5Etfw">@cablockchain</a>, <a href="https://twitter.com/barreaunantes?ref_src=twsrc%5Etfw">@barreaunantes</a> et <a href="https://twitter.com/_emblock?ref_src=twsrc%5Etfw">@_emblock</a> <a href="https://t.co/vDbmPImS7x">pic.twitter.com/vDbmPImS7x</a></p>— Dominique Pellat (@dpellat) <a href="https://twitter.com/dpellat/status/1306649975024226307?ref_src=twsrc%5Etfw">September 17, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Le pitch :</p>
<blockquote>
<p>Smart Contracts, Cryptomonnaie, Dencentralized Autonomous Organization, la blockchain révolutionne l’économie, les modes de collaboration et de partage d’aujourd’hui. De nombreuses perspectives d’évolution sont encore à étudier et à développer.</p>
<p>Le recours à cette technologie bouscule également les principes juridiques traditionnels : le smart contract est-il un contrat ? Peut-on recourir à la blockchain comme mode de preuve ? Peut-on juridiquement traiter les données personnelles sur la blockchain ?</p>
<p>Au cours d’un table ronde d’1h à 1h30 réunissant des professionnels de l’écosystème nantais de la blockchain et deux avocats nantais en droit du numérique, Delphine Ganoote Mary et Julie Bader, nous évoquerons ensemble ces sujets.</p>
<p>L’objectif de cette table ronde interactive et participative serait d’échanger avec les participants sur la blockchain, ses impacts dans notre société et les évolutions de l’environnement juridique à cet égard.</p>
<p>Cette table ronde permettra également de montrer l’implication d’acteurs nantais dans le développement et le rayonnement de cette technologie.</p>
</blockquote>
<p>Malheureusement, il n'existe pas beaucoup de traces de nos échanges, il fallait être présent pour en profiter 😄</p>
<p>J'ai beaucoup appris avec Julie et Delphine, elles maîtrisent vraiment les sujets juridiques "techs" : blockchain, open-source, licences open-source et propriété intellectuelle ...</p>
<p>Je vous les recommande !</p>
Libra : pour le meilleur ou pour le pire ?
2019-09-20T00:00:00+00:00
2019-09-20T00:00:00+00:00
https://dlecan.com/blog/libra-pour-pire-pour-meilleur/
<p>J'ai animé <a rel="noopener" target="_blank" href="https://www.meetup.com/fr-FR/Blockchain-Societe-Nantes/events/264350213/">une présentation sur la cryptomonnaie Libra de Facebook</a> le 18 septembre 2019 chez HLP Audit dans le cadre des meetups organisés par <a rel="noopener" target="_blank" href="https://blockchainsociete.org">l'association Blockchain et Société</a>.</p>
<span id="continue-reading"></span><h2 id="le-pitch">Le pitch</h2>
<blockquote>
<p>🌊 La cryptomonnaie Libra annoncée par Facebook a largement défrayé la chronique ces dernières semaines.
Afin d'en savoir plus, c'est donc une soirée spéciale "Libra" que nous vous proposons, en deux temps :
⚖ Présentation des FAITS concernant Libra 🤓</p>
<p>Durant 30 min, nous revenons sur les éléments connus de Libra : les white-papers, le code source publié ainsi que différents éléments de communication de la fondation, de ses membres et de Facebook.</p>
</blockquote>
<h2 id="les-slides">Les slides</h2>
<figure class="image is-16by9">
<iframe class="has-ratio" src="https://docs.google.com/presentation/d/e/2PACX-1vRdLKcd-u4G8hkJqwmXADuoK7lhnLH-WTA9owpStQhXQ3cLdD0IX_LCWCMR8wwbBtgMmARbknFLeeRK/embed?start=false&loop=false&delayms=60000" frameborder="0" width="560" height="349" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</figure>
Serious game 'Jouons à la Blockchain' pour l'inauguration de Novapuls
2018-12-10T00:00:00+00:00
2018-12-10T00:00:00+00:00
https://dlecan.com/blog/inauguration-novapuls-jouons-blockchain/
<p><a rel="noopener" target="_blank" href="https://twitter.com/lauremerlin">Laure Merlin</a> et moi avons animé un <em>serious game</em> grandeur nature sur le thème de la Blockchain pour l'inauguration de <a rel="noopener" target="_blank" href="https://novapuls.fr/">l'incubateur de start-ups nantais Novapuls</a>.</p>
<span id="continue-reading"></span>
<p>Cet atelier, nommé "Jouons à la Blockchain" a eu lieu le mercredi 05 décembre 2018.</p>
<p>Par groupe de 4-6 personnes, la quarantaine de participants a joué à la Blockchain avec des Legos : miner par preuve de travail (Proof-of-Work - PoW) ou preuve de possession (Proof-of-Stake - PoS), diffuser des informations ou des blocs, enregistrer des informations, résister à des <em>hacks</em>, executer des <em>smart-contracts</em> ... tout le monde s'est pris au jeu !</p>
<p>Quelques images :</p>
<p><a rel="noopener" target="_blank" href="https://www.linkedin.com/feed/update/urn:li:activity:6476009903461924864"><img src="linkedin_post.jpg" alt="Damien Lecan à Novapuls sur un post linkedIn" /></a></p>
<blockquote class="twitter-tweet"><p lang="fr" dir="ltr">[Inauguration <a href="https://twitter.com/Novapuls_ouest?ref_src=twsrc%5Etfw">@Novapuls_ouest</a> ] Tout comprendre sur la <a href="https://twitter.com/hashtag/blockchain?src=hash&ref_src=twsrc%5Etfw">#blockchain</a> avec <a href="https://twitter.com/lauremerlin?ref_src=twsrc%5Etfw">@lauremerlin</a> et <a href="https://twitter.com/dlecan?ref_src=twsrc%5Etfw">@dlecan</a>. Jouons aux legos chez <a href="https://twitter.com/SoderoGestion?ref_src=twsrc%5Etfw">@SoderoGestion</a> pour comprendre le noeud, le bloc, le minage, la fraude, le smart contract,... <a href="https://t.co/cUlpvbqvJF">pic.twitter.com/cUlpvbqvJF</a></p>— Amélie André (@Amelie_novapuls) <a href="https://twitter.com/Amelie_novapuls/status/1070236752076517376?ref_src=twsrc%5Etfw">December 5, 2018</a></blockquote>
<blockquote class="twitter-tweet"><p lang="fr" dir="ltr"><a href="https://twitter.com/hashtag/Inauguration?src=hash&ref_src=twsrc%5Etfw">#Inauguration</a> 🚀 l Atelier conférence : Jouons ensemble à la <a href="https://twitter.com/hashtag/Blockchain?src=hash&ref_src=twsrc%5Etfw">#Blockchain</a> par <a href="https://twitter.com/dlecan?ref_src=twsrc%5Etfw">@dlecan</a> CTO de <a href="https://twitter.com/UnikName_Uns?ref_src=twsrc%5Etfw">@UnikName_UNS</a> et <a href="https://twitter.com/lauremerlin?ref_src=twsrc%5Etfw">@lauremerlin</a> CEO de <a href="https://twitter.com/ChainSpring?ref_src=twsrc%5Etfw">@ChainSpring</a> 😉 <a href="https://twitter.com/hashtag/startups?src=hash&ref_src=twsrc%5Etfw">#startups</a> <a href="https://twitter.com/hashtag/cryptocurrency?src=hash&ref_src=twsrc%5Etfw">#cryptocurrency</a> <a href="https://t.co/ffbDhNIdTc">pic.twitter.com/ffbDhNIdTc</a></p>— Novapuls (@Novapuls_ouest) <a href="https://twitter.com/Novapuls_ouest/status/1070233162565996544?ref_src=twsrc%5Etfw">December 5, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Un succès aux dires des participants et des organisateurs 😅</p>
<p>Merci au public présent et à Novapuls pour sa confiance.</p>
'État de l'art des Blockchains & co.' à Blockchain Paris 2018
2018-12-07T00:00:00+00:00
2018-12-07T00:00:00+00:00
https://dlecan.com/blog/keynote-blockchain-paris-etat-art/
<p>J'ai présenté la semaine dernière <a rel="noopener" target="_blank" href="https://blockchainevent.fr/2018/speakers/damien-lecan/">la keynote "État de l'art de Blockchain & co."</a> à <a rel="noopener" target="_blank" href="https://blockchainevent.fr/2018/">Blockchain Paris 2018</a> à la Cité Universitaire Internationale.
L'occasion de revenir sur les bases de la Blockchain.</p>
<span id="continue-reading"></span>
<p>Quelques éléments que j'ai présentés :</p>
<ul>
<li>ses valeurs : la confiance, qui vient de immuabilité, transparence, la décentralisation et la désintermédiation</li>
<li>des modèles de gouvernance : publique, privée, consortium ...</li>
<li>un état rapide du marché et de ses entreprises</li>
<li>et de finir sur le challenge du moment : soutenir les entreprises du secteur malgré le contexte "crypto" morose (ça n'a aucun rapport, mais le bébé part avec l'eau du bain en ce moment)</li>
</ul>
<h2 id="les-slides">Les slides</h2>
<figure class="image is-16by9">
<iframe class="has-ratio" src="https://docs.google.com/presentation/d/e/2PACX-1vSXfdvrmc3N6tSMAekUYySxawdomejhRfx9lzSzIshDqpAg7y-0KCAdnu723m7GdeTvrpc-WE4QqfqA/embed?start=false&loop=false&delayms=60000" frameborder="0" width="560" height="349" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</figure>
<p>Merci au public présent !</p>
'Another World, another Web' au Web2day 2018
2018-06-16T00:00:00+00:00
2018-06-16T00:00:00+00:00
https://dlecan.com/blog/web2day2018-another-world-another-web-decentralisation/
<p>Avec <a rel="noopener" target="_blank" href="https://twitter.com/guiillaumeN">GuiillaumeN</a>, j'ai eu l'honneur de présenter <a rel="noopener" target="_blank" href="https://web2day.co/evenements/another-world-another-web/">"Another World, another Web" au Web2day 2018</a>, sur le thème du web décentralisé et distribué.</p>
<span id="continue-reading"></span><h2 id="le-pitch">Le pitch</h2>
<blockquote>
<p>Vous rêvez d’un site web à la fois sécurisé, disponible 24/7j, fiable et respectueux de la vie privée ?
Une architecture classique mêlerait cloud, load-balancers, chiffrement … plutôt compliqué pour des besoins élémentaires.</p>
<p>Figurez vous qu’un autre monde existe déjà et se trouve à votre portée. Noms de domaines, stockage et distribution des fichiers, logique métier décentralisée, navigateurs adaptés … nous allons tout vous présenter !</p>
<p>Voyage dans un autre monde, au coeur du Web décentralisé.</p>
</blockquote>
<h2 id="la-video">La vidéo</h2>
<div class="youtube is-flex is-justify-content-center is-align-items-center">
<iframe
width="848" height="510"
src="https://www.youtube.com/embed/_0hO9uKDlok"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div><h2 id="les-slides">Les slides</h2>
<figure class="image is-16by9">
<iframe class="has-ratio" src="https://docs.google.com/presentation/d/e/2PACX-1vTVdjK6h78FPaYWS9C8d4In_LJt8dkaxe1RW2rkY6oUbF3nwDd9VH7jBVD2zU2hfD5BSSR1GtsCU7_Z/embed?start=false&loop=false&delayms=60000" frameborder="0" width="560" height="349" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</figure>
<p>Merci au public présent !</p>
'Smart-contracts under attack' au GDG Toulouse
2018-06-06T00:00:00+00:00
2018-06-06T00:00:00+00:00
https://dlecan.com/blog/meetup-gdg-toulouse-blockchain-smart-contract-security/
<p>J'ai été invité le 5 juin 2018 à venir parler des <em>smart-contracts</em> Ethereum au <a rel="noopener" target="_blank" href="https://www.meetup.com/fr-FR/GDG-Toulouse/events/250099870/">GDG Toulouse</a>.</p>
<span id="continue-reading"></span>
<p>Avec <a rel="noopener" target="_blank" href="https://twitter.com/polo46">Paul Marty</a>, expert sécurité chez Orange Cybersécurité, nous avons orienté notre présentation autour de la sécurité des <em>smart-contracts</em>, avec une séance de live-coding avec attaque en direct : moi, développeur un peu naif, qui déploie des <em>smart-contrats</em> sur Ethereum et Paul qui siphonne l'argent en temps réel 😅.</p>
<p>Une belle soirée sur Toulouse !</p>
<p>Les slides de notre présentation :</p>
<figure class="image is-16by9">
<iframe class="has-ratio" src="https://docs.google.com/presentation/d/e/2PACX-1vSuT2L6_82F7WhApJ6Ehdgj41bzPSkBRlFSXrZoay5aVqmf45kgcX_8sfq53m_j8PubUdWl642bqWH0/embed?start=false&loop=false&delayms=60000" frameborder="0" width="560" height="349" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</figure>
<p>La vidéo :</p>
<div class="youtube is-flex is-justify-content-center is-align-items-center">
<iframe
width="848" height="510"
src="https://www.youtube.com/embed/rQywiljTQdg"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>
<p>Merci au public présent !</p>
'Proof-of-Stake' au meetup Blockchain et Société
2018-05-18T00:00:00+00:00
2018-05-18T00:00:00+00:00
https://dlecan.com/blog/meetup-blockchain-proof-stake/
<p>Hier soir, j'ai eu le plaisir de présenter une conférence à base de gâteau Michel et Augustin 🤣 présentant la "Proof-Of-Stake" ou preuve d'enjeu au <a rel="noopener" target="_blank" href="https://www.meetup.com/fr-FR/Blockchain-Societe-Nantes/events/250342863/">meetup de mai</a> de <a rel="noopener" target="_blank" href="https://blockchainsociete.org">l'association Blockchain et Société</a>.</p>
<span id="continue-reading"></span><h2 id="le-pitch">Le pitch</h2>
<blockquote>
<p>🍟 Introduction à la Proof-Of-Stake 🍟</p>
<p>La Proof-Of-Work (PoW) est reine dans le domaine des blockchains publiques comme Bitcoin ou Ethereum, mais elle n'est pas sans inconvénients.
La Proof-Of-Stake (PoS) est bien placée pour remplacer la PoW, mais comment-fonctionne-t-elle ?
Qu'apporte-t-elle ? Pourquoi n'a-t-elle pas remplacé la PoW ?</p>
<p>Agenda</p>
<ul>
<li>Introduction à la PoS</li>
<li>Présentation de Qtum, une blockchain qui est mue nativement par la PoS</li>
</ul>
</blockquote>
<p>Une belle soirée !</p>
<p>Les slides de ma présentation :</p>
<figure class="image is-16by9">
<iframe class="has-ratio" src="https://docs.google.com/presentation/d/e/2PACX-1vSZhUnxaXOfdtWbT-dsiIxsVIbmkQlwP09i4Hu7HfQ6NGxjD1l92gId5i6DuA30qTnrIxMOeE9sa41q/embed?start=false&loop=false&delayms=60000" frameborder="0" width="560" height="349" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</figure>
<p>Merci au public présent !</p>
Le Web décentralisé au GDG Nantes
2018-01-23T00:00:00+00:00
2018-01-23T00:00:00+00:00
https://dlecan.com/blog/blockchain-decentralisation-tested-deployed-approved/
<p><a rel="noopener" target="_blank" href="https://twitter.com/guiillaumeN">GuiillaumeN</a> et moi avons été invités par le <a rel="noopener" target="_blank" href="https://www.meetup.com/fr-FR/GDG-Nantes/">GDG Nantes</a> à présenter notre conférence "Web décentralisé : testé, déployé, approuvé ✅ !" fin janvier 2018.</p>
<span id="continue-reading"></span><h2 id="web-decentralise-teste-deploye-approuve-white-check-mark">Web décentralisé : testé, déployé, approuvé ✅ !</h2>
<p>Une belle occasion pour présenter la notion de <a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/%C3%90">Ð</a>app, des applications Web décentralisées, à la fois sur le code métier (dé)localisé dans une blockchain <a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Ethereum">Ethereum</a>, mais aussi sur tous les assets nécessaires à l'application (Javacript, CSS, HTML ...), (dé)localisés eux dans un système de fichier réparti comme <a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/InterPlanetary_File_System">IPFS</a>.</p>
<p>Les slides de notre présentation :</p>
<figure class="image is-16by9">
<iframe class="has-ratio" src="https://docs.google.com/presentation/d/e/2PACX-1vRg9iV-YbON8rNSH159OMZhuoExZ0pr4RZvoJ1Dx4gHTZoNkIJAuipC_nDQpwFSSfsSmqntAAY3bbbN/embed?start=false&loop=false&delayms=60000" frameborder="0" width="560" height="349" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</figure>
<p>Merci au public présent !</p>
'Ethereum de A à Z' au meetup Blockchain et Société
2017-11-16T00:00:00+00:00
2017-11-16T00:00:00+00:00
https://dlecan.com/blog/meetup-blockchain-ethereum-a-z/
<p>Hier soir, j'ai eu le plaisir de présenter avec <a rel="noopener" target="_blank" href="https://twitter.com/guiillaumeN">GuiillaumeN</a> et <a rel="noopener" target="_blank" href="https://twitter.com/benjifontaine5">Benjamin</a> notre conférence "Ethereum, de A(lliance) à Z(k-snarks)" au <a rel="noopener" target="_blank" href="https://www.meetup.com/fr-FR/Blockchain-Societe-Nantes/events/244570850/">meetup de novembre</a> de <a rel="noopener" target="_blank" href="https://blockchainsociete.org">l'association Blockchain et Société</a>.</p>
<span id="continue-reading"></span>
<blockquote>
<p>Soirée spéciale Ethereum, la Blockchain en pleine croissance !</p>
<p>Nous vous présenterons tous les concepts de la plateforme :</p>
<ul>
<li>Origine, gouvernance, culture</li>
<li>Écosystème et outils : Geth, Parity, Web3, Quorum, Mist ...</li>
<li>Roadmap : Homestead, Metropolis ...</li>
</ul>
<p>Nous finirons par une séance de questions-réponses. Par exemple : qu'est-ce que l'Ethereum Enterprise Alliance ? Que sont les hard-forks ? ...</p>
</blockquote>
<p>Une belle soirée !</p>
<p>Les slides de notre présentation :</p>
<figure class="image is-16by9">
<iframe class="has-ratio" src="https://docs.google.com/presentation/d/e/2PACX-1vTz2ykgmnij1V3v9prs07qepDMA5SligE55O3ikitVfD4H-aM-6tJ10JiuWU2y6Q3zfK8jxV2CqCK6Q/embed?start=false&loop=false&delayms=60000" frameborder="0" width="560" height="349" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</figure>
<p>Merci au public présent !</p>
'Go & Rust' au meetup SQLI Nantes 2015
2017-07-07T00:00:00+00:00
2017-07-07T00:00:00+00:00
https://dlecan.com/blog/meetup-sqli-nantes-2015-golang-rust/
<p><a rel="noopener" target="_blank" href="https://golang.org/">Go</a> et <a rel="noopener" target="_blank" href="https://www.rust-lang.org/">Rust</a> font partie de ses "nouveaux" langages très excitants : à la fois modernes mais aussi très puissants.
Je les ai présentés et comparés lors de ce meetup organisé par <a rel="noopener" target="_blank" href="http://www.sqli.com/">SQLI Nantes</a> en juillet 2015.</p>
<span id="continue-reading"></span>
<p>Support de présentation :</p>
<p><a rel="noopener" target="_blank" href="http://dlecan.github.io/meetupsqlinantes2015-prez/#2"><img src="cover.png" alt="Support de présentation de la conférence" /></a></p>
<p>La vidéo (à partir de 66' pour ma conférence "Go & Rust") :</p>
<div class="youtube is-flex is-justify-content-center is-align-items-center">
<iframe
width="848" height="510"
src="https://www.youtube.com/embed/OKg9gIs6W0Y"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>
'Smartphone et Blockchain' au Breizhcamp 2017
2017-05-05T00:00:00+00:00
2017-05-05T00:00:00+00:00
https://dlecan.com/blog/smartphone-blockchain-armes-revolution-massive/
<p>J'ai eu le plaisir co-animer avec <a rel="noopener" target="_blank" href="https://twitter.com/guiillaumeN">GuiillaumeN</a> au <a rel="noopener" target="_blank" href="http://www.breizhcamp.org/">Breizhcamp 2017</a> une conférence sur la blockchain.</p>
<span id="continue-reading"></span>
<p>Les slides de la présentation "Smartphone et Blockchain, armes de révolution massive" sont disponibles sur Github :</p>
<p><a rel="noopener" target="_blank" href="https://the-blockchain-machine.github.io/breizhcamp2017_revolution-blockchain-mobile-android/"><img src="cover.png" alt="Slides de la conférence Smartphone et Blockchain, armes de révolution massive" /></a></p>
Introduction au langage de programmation Rust - Partie 3
2017-03-17T00:00:00+00:00
2017-03-17T00:00:00+00:00
https://dlecan.com/blog/introduction-rust-part-3/
<blockquote>
<p>Initialement publié sur <a rel="noopener" target="_blank" href="https://www.technologies-ebusiness.com/langages/introduction-a-rust-partie-3">https://www.technologies-ebusiness.com/langages/introduction-a-rust-partie-3</a></p>
</blockquote>
<p>Après avoir vu comment installer le compilateur Rust et Cargo, puis écrit quelques lignes de code dans la <a href="/introduction-rust-part-2/">seconde partie de cette introduction</a>, nous allons continuer dans cette troisième partie à faire évoluer notre programme en découvrant de nouvelles caractéristiques de Rust.</p>
<p>Avant de nous lancer, rappelez-vous, une nouvelle version de Rust est publiée toutes les six semaines ; il est donc très probable que la version que vous avez installée est déjà obsolète.</p>
<p>Mettez à jour Rustup lui-même, puis ensuite Rust :</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>$ rustup self update // mise à jour de Rustup
</span><span> ...
</span><span>$ rustup update // mise à jour de tous les canaux de Rust installés
</span></code></pre>
<p>Pensez à effectuer régulièrement ces opérations : une version à jour de Rust vous donne accès à de nouvelles fonctionnalités et une meilleure compatibilité avec les librairies de la communauté.</p>
<h2 id="struct-et-trait"><code>Struct</code> et <code>trait</code></h2>
<p>Notre programme des deux premières parties était structuré de manière procédurale. Nous allons lui donner une allure plus lisible et plus encapsulée, pour ne pas dire plus "objet". Rust n’a pas pour autant des "classes" comme dans d’autres langages, mais des <code>struct</code> et des <code>trait</code>.</p>
<p>Comme leur nom l’indique, les struct sont des structures qui permettent de stocker un ensemble de données complexes ; on dira qu’une struct définie un nouveau type. Notez qu’il n’y a pas de constructeur ou d’accesseurs à proprement parler comme dans d’autre langage, Rust reste très simple ici.</p>
<p>Faisons évoluer notre programme en introduisant une <em>struct</em> :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">struct </span><span>Division {
</span><span> </span><span style="color:#bf616a;">numerateur</span><span>: </span><span style="color:#b48ead;">i32</span><span>,
</span><span> </span><span style="color:#bf616a;">denominateur</span><span>: </span><span style="color:#b48ead;">i32</span><span>,
</span><span>}
</span></code></pre>
<p>La structure peut-être ensuite instanciée et ses propriétés manipulées :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">let</span><span> une_division = Division {numerateur: </span><span style="color:#d08770;">10</span><span>, denominateur: </span><span style="color:#d08770;">12</span><span>};
</span><span>
</span><span>println!("</span><span style="color:#a3be8c;">Une division (</span><span style="color:#d08770;">{}</span><span style="color:#a3be8c;"> - </span><span style="color:#d08770;">{}</span><span style="color:#a3be8c;">)</span><span>", une_division.numerateur, une_division.denominateur);
</span></code></pre>
<p>Continuons notre logique d’encapsulation en ajoutant des méthodes à notre structure. Ici, la syntaxe de Rust sort vraiment de l’ordinaire. En effet, les méthodes ne sont pas ajoutées directement dans le corps de la <em>struct</em>, mais déclarées où vous le souhaitez dans votre programme avec le mot-clé impl.</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">impl </span><span>Division {
</span><span> </span><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">calculer</span><span>(&</span><span style="color:#bf616a;">self</span><span>) -> </span><span style="color:#b48ead;">i32 </span><span>{
</span><span> </span><span style="color:#b48ead;">match </span><span style="color:#bf616a;">self</span><span>.denominateur {
</span><span> </span><span style="color:#d08770;">0 </span><span>=> panic!("</span><span style="color:#a3be8c;">Division par 0</span><span>"),
</span><span> </span><span style="color:#d08770;">1 </span><span>=> </span><span style="color:#bf616a;">self</span><span>.numerateur,
</span><span> _ => </span><span style="color:#bf616a;">self</span><span>.numerateur / </span><span style="color:#bf616a;">self</span><span>.denominateur
</span><span> }
</span><span> }
</span><span>}
</span></code></pre>
<p>Le code de la méthode calculer est repris de la méthode <code>calculer_division</code> vu dans la précédente partie de cet article.</p>
<p>Il est tentant de penser qu’on peut faire n’importe quoi, comme en Javascript, à savoir rajouter des méthodes à n’importe quelle <em>struct</em>, écrite par vous ou fournie par le langage. Par exemple, en Javascript, on peut rajouter des méthodes au prototype <code>String</code> et les utiliser comme des méthodes du langage (cette capacité est notamment utilisée par tous les polyfills).</p>
<p>En Rust, il est impossible d’ajouter des méthodes à n’importe quelle <em>struct</em> ; les <code>impl</code> doivent être déclarés dans le même module (<code>crates</code> en Rust) que la <em>struct</em>.</p>
<p>Mettez à jour votre programme Rust :</p>
<ul>
<li>déclarer le nouveau type <code>Division</code> à l’aide d’une <em>struct</em></li>
<li>remplacer la déclaration de la méthode statique <code>calculer_division</code> par une méthode <code>calculer</code> qui implémente le type <code>Division</code> (attention à la signature de la méthode <code>calculer</code>)</li>
<li>remplacer l’appel à la méthode <code>calculer_division</code> par l’instanciation du type <code>Division</code> avec le paramètre qui vient de l’analyse de la ligne de commande, puis calculer le résultat et l’afficher.</li>
</ul>
<p>A ce stade, vous devez avoir un programme qui compile et s’exécute, ce que vous pouvez vérifier à l’aide de la commande <code>cargo run 4</code> (code complet <a rel="noopener" target="_blank" href="https://git.io/v1XJL">https://git.io/v1XJL</a>).</p>
<p>S’il n’existe pas de "vrai" constructeur en Rust, les us et coutumes du langage encouragent cependant l’encapsulation de l’opération d’instanciation d’un type au sein d’une fonction statique déclarée dans l’implémentation de la struct elle-même, nommée par convention <code>new</code> et qui retourne évidemment une instance de votre type. Ce qui donne pour <code>Division</code> :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">impl </span><span>Division {
</span><span> </span><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">new</span><span>(</span><span style="color:#bf616a;">x</span><span>: </span><span style="color:#b48ead;">i32</span><span>, </span><span style="color:#bf616a;">y</span><span>: </span><span style="color:#b48ead;">i32</span><span>) -> Division {
</span><span> Division {
</span><span> numerateur: x,
</span><span> denominateur: y,
</span><span> }
</span><span> }
</span><span> ...
</span><span>}
</span></code></pre>
<p>Pensez à remplacer l’instanciation manuelle de <code>Division</code> dans votre programme par l’usage de la fonction <code>new</code> (code complet <a rel="noopener" target="_blank" href="https://git.io/v1XLo">https://git.io/v1XLo</a>).</p>
<p>Outre les <code>struct</code>, Rust propose un autre mécanisme qui permet d’indiquer au compilateur les fonctionnalités qu’un type doit obligatoirement fournir : les <code>trait</code>. Par exemple, si nous souhaitons constraindre la façon dont une Division doit déclarer le symbole qu’elle représente, nous pouvons déclarer le <em>trait</em> suivant :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">trait </span><span>HasSymbol {
</span><span> </span><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">symbol</span><span>(&</span><span style="color:#bf616a;">self</span><span>) -> String;
</span><span>}
</span></code></pre>
<p>Les <em>traits</em> ressemblent aux interfaces Java ou C#, avec globalement les mêmes caractéristiques :</p>
<ul>
<li>ensemble de fonctions que le type doit obligatoirement redéfinir</li>
<li>certaines fonctions peuvent avoir une implémentation par défaut</li>
<li>un <em>trait</em> peut implémenter un autre <em>trait</em>, et donc "hériter" de ses caractéristiques (concrètement, il faudra implémenter les deux traits sur votre type)</li>
</ul>
<p>Implémentons notre <em>trait</em> pour la <code>Division</code> :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">impl </span><span>HasSymbol </span><span style="color:#b48ead;">for </span><span>Division {
</span><span> </span><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">symbol</span><span>(&</span><span style="color:#bf616a;">self</span><span>) -> String {
</span><span> "</span><span style="color:#a3be8c;">/</span><span>".</span><span style="color:#96b5b4;">to_string</span><span>() </span><span style="color:#65737e;">// "/" est du type &str, qu'il faut donc convertir
</span><span> }
</span><span>}
</span></code></pre>
<p>Notez ce point important, impossible en Java par exemple : implémenter un <em>trait</em> pour un type est une section de code déclarée a posteriori de la déclaration de ce type, ce qui veut dire qu’un nouveau *trait *peut enrichir retrospectivement un type existant (avec quelques restrictions cependant).</p>
<p>Désormais, il est possible de tracer le symbole de la <code>Division</code>, juste après sa construction par exemple :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">let</span><span> division = Division::new(numerateur, </span><span style="color:#d08770;">2</span><span>);
</span><span>println!("</span><span style="color:#a3be8c;">Symbole : </span><span style="color:#d08770;">{}</span><span>", division.</span><span style="color:#96b5b4;">symbol</span><span>());
</span></code></pre>
<p>Le résultat d’exécution de votre programme est désormais enrichi du symbole de la Division (code complet <a rel="noopener" target="_blank" href="https://git.io/v1X4I">https://git.io/v1X4I</a>) :</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>$ cargo run 2
</span><span> Running `target/debug/division 2`
</span><span>Symbole: /
</span><span>Résultat : 1
</span></code></pre>
<h2 id="encore-quelques-concepts-a-maitriser-par-le-rustaceen-qui-debute">Encore quelques concepts à maîtriser par le Rustacéen qui débute</h2>
<p>Vous vous en souvenez peut-être, je vous avais promis dans la première partie de cet article de la sueur, en particulier avec la gestion de la mémoire : elle n’est ni à la charge du développeur, ni à la charge d’une machine virtuelle et de son ramasse-miette.</p>
<p>Il est temps de mettre les mains dans le camboui et de transpirer. Accrochez-vous !</p>
<p>Reprenons le code décrit plus haut, et ajoutons-y une instruction qui paraît anodine :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">let</span><span> division = Division::new(numerateur, </span><span style="color:#d08770;">2</span><span>);
</span><span style="color:#b48ead;">let</span><span> division2 = division; </span><span style="color:#65737e;">// <= instruction anodine :-)
</span><span>println!("</span><span style="color:#a3be8c;">Symbole : </span><span style="color:#d08770;">{}</span><span>", division.</span><span style="color:#96b5b4;">symbol</span><span>());
</span></code></pre>
<p>Que se passe-t-il à la compilation (<code>cargo build</code>) ?</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>error[E0382]: use of moved value: `division`
</span><span> --> src/main.rs:48:30
</span><span> |
</span><span>47 | let division2 = division;
</span><span> | ---------value moved here
</span><span>48 | println!("Symbole : {}", division.symbol());
</span><span> | ^^^^^^^^ value used here after move
</span><span> |
</span><span> = note: move occurs because `division` has type `Division`, which
</span><span> does not implement the `Copy` trait
</span></code></pre>
<p>Le compilateur Rust vous indique que la valeur pointée par la variable division est déplacée (<em>moved</em>). En effet, une valeur ne peut être référencée que par une seule variable dans tout notre code. C’est le concept de possession (<em>ownership</em>), contrôlée à la lettre par le compilateur, qui va garantir la sécurité et la robustesse d’exécution d’un programme Rust. Nous avons déplacé la possession de la valeur de division vers division2, par conséquent, division ne peut plus être utilisée.</p>
<p>Qui dit "possession", dit "emprunt" (<em>borrowing</em>) ou "copie" et pour illustrer l’une ou l’autre des solutions, nous allons introduire une nouvelle fonction statique et l’utiliser (code complet <a rel="noopener" target="_blank" href="https://git.io/v1X2m">https://git.io/v1X2m</a>):</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">display_symbol</span><span>(</span><span style="color:#bf616a;">division</span><span>: Division) {
</span><span> println!("</span><span style="color:#a3be8c;">Symbole: </span><span style="color:#d08770;">{}</span><span>", division.</span><span style="color:#96b5b4;">symbol</span><span>());
</span><span>}
</span><span>...
</span><span style="color:#b48ead;">let</span><span> division = Division::new(numerateur, </span><span style="color:#d08770;">2</span><span>);
</span><span style="color:#96b5b4;">display_symbol</span><span>(division); </span><span style="color:#65737e;">// <= à la place du 'let division2 = ...'
</span></code></pre>
<p>Ce code ne compile pas et vous optenez un message d’erreur très similaire au précédent. Trois solutions pour résoudre cette erreur de compilation s’offrent à nous :</p>
<p>1/ Ne plus utiliser la variable division après l’appel à la méthode <code>display_symbol</code></p>
<p>2/ Copier toute la valeur de la variable</p>
<p>3/ Permettre l’emprunt de la variable et utiliser sa référence</p>
<p>La solution 1/ est une façon de mettre le problème sous le tapis ou de le repousser, ce n’est pas vraiment une solution (même si le programme compilera effectivement 😉</p>
<p>Copier toute la valeur de la variable (solution 2) est une façon intéressante de résoudre le problème. Dans cette solution, la valeur de la variable est entièrement copiée lors de l’appel à la fonction. Notez bien qu’il n’y a donc plus de lien entre la variable déclarée avant l’appel de la fonction et la variable utilisée dans la fonction.</p>
<p>Pour déclarer un type "copiable", il suffit d’implémenter le <em>trait</em> <code>Copy</code>, ainsi que le <em>trait</em> <code>Clone</code> dont hérite <code>Copy</code>. Le plus simple, est d’utiliser l’implémentation automatique de certains traits, proposée par l’attribut <code>#[derive(...)]</code> (documentation : <a rel="noopener" target="_blank" href="https://bit.ly/2hASRHt">https://bit.ly/2hASRHt</a>), à appliquer directement sur un type :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span>#[</span><span style="color:#bf616a;">derive</span><span>(Copy, Clone)]
</span><span>Division {
</span><span> ...
</span></code></pre>
<p>Avec cet ajout, notre programme compile de nouveau (code complet <a rel="noopener" target="_blank" href="https://git.io/v11tL">https://git.io/v11tL</a>). Cependant, si cette solution peut sembler magique et simple (et de plus proposée par le compilateur), elle a ausi ses limites :</p>
<ul>
<li>un type peut implémenter <code>Copy</code> uniquement si l’ensemble de ses composants implémente aussi <code>Copy</code> (dans notre exemple, <code>i32</code> implémente <code>Copy</code>, donc <code>Division</code> peut implémenter <code>Copy</code>). Pour les Javaistes, on retrouve ici une propriété équivalente dans l’esprit aux objets sérialisables</li>
<li>un certain nombre de types n’implémentent pas <code>Copy</code> ; par oubli du développeur ou par incompatibililté technique. Par exemple, les <code>String</code> ne sont pas compatibles avec <code>Copy</code>.</li>
</ul>
<p>La troisième et dernière solution s’applique donc à tous les autres cas. Elle s’appuie sur le principe de l’emprunt, à savoir qu’on va passer à notre fonction non pas la valeur d’une variable, mais une référence vers la valeur de cette variable.</p>
<p>Concrètement, il faut faire évoluer la signature de notre fonction d’affichage pour permettre l’emprunt et l’usage de référence :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">display_symbol</span><span>(</span><span style="color:#bf616a;">division</span><span>: &Division) { </span><span style="color:#65737e;">// <= Notez le & ici
</span><span> ...
</span><span>}
</span><span>...
</span><span style="color:#b48ead;">let</span><span> division = Division::new(numerateur, </span><span style="color:#d08770;">2</span><span>);
</span><span style="color:#96b5b4;">display_symbol</span><span>(&division); </span><span style="color:#65737e;">// <= Notez le & ici
</span></code></pre>
<p>La fonction <code>display_symbol</code> attend une référence vers un type <code>Division</code>, identifiée par le symbole <code>&</code> et nous pouvons passer la référence vers une valeur en ajoutant le même symbole devant le nom d’une variable (code complet <a rel="noopener" target="_blank" href="https://git.io/v11ml">https://git.io/v11ml</a>). Cette solution est la plus universelle, au prix d’une complexité intellectuelle plus élevée.</p>
<p>Finalement, grâce à ces différents mécanismes, le cycle de vie de toutes les données référencées par des variables, est connu dès la compilation de votre programme, ce qui garantit une bonne gestion de la mémoire et donc une certaine robustesse. En revanche, elle vous garantit aussi quelques "combats" contre le borrow checker du compilateur Rust.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Au cours de ces trois articles d’introduction à Rust, nous avons abordés les outils et les concepts les plus importants du langage : <em>struct</em>, <em>trait</em>, <em>pattern matching</em>, <em>enum</em>, possession (<em>ownership</em>), emprunt (<em>borrowing</em>), notions de programmation fonctionnelle ... Ces connaissances devraient être suffisantes pour écrire vos premiers programmes avec Rust.</p>
<p>Vous découvrirez par vous-même des concepts plus avancés du langage comme les <em>lifetimes</em>, les types génériques, les modules et les <em>crates</em>, les <em>macros</em>, les tests, les itérateurs, la concurrence, la gestion des erreurs ... La lecture du livre "The Rust programming language" sera donc à ce propos un bon point de départ pour vous : <a rel="noopener" target="_blank" href="https://doc.rust-lang.org/book/">https://doc.rust-lang.org/book/</a>. Enfin, tous ces concepts pourraient faire l’objet d’articles dédiés, avis donc aux amateurs !</p>
Introduction au langage de programmation Rust - Partie 2
2017-03-14T00:00:00+00:00
2017-03-14T00:00:00+00:00
https://dlecan.com/blog/introduction-rust-part-2/
<blockquote>
<p>Article initialement publié sur <a rel="noopener" target="_blank" href="https://www.technologies-ebusiness.com/langages/introduction-a-rust-partie-2">https://www.technologies-ebusiness.com/langages/introduction-a-rust-partie-2</a></p>
</blockquote>
<p>Nous poursuivons notre découverte du langage Rust après <a href="/introduction-rust-part-1/">une première partie</a> dans laquelle vous avez pratiqué quelques concepts de base de Rust : éléments de syntaxe, déclaration de variables immuables, fonctions et matching. Si la pratique de Rust directement dans le navigateur était adaptée pour débuter, je vous propose désormais de développer directement sur votre poste. Nous pourrons alors continuer à explorer les possibilités de Rust.
Installer Rust</p>
<p>Le site officiel <a rel="noopener" target="_blank" href="https://www.rust-lang.org">https://www.rust-lang.org</a> propose des binaires ou des installeurs pour Linux, Mac ou Windows, qui ne se mettent pas à jour automatiquement. Sachant qu’une nouvelle version du langage Rust et des outils est publiée toutes les six semaines et que l’on est régulièrement amené à jongler entre les différents channels de Rust (stable, beta, nightly), je vous déconseille cette façon d’installer Rust.</p>
<p>Préférez plutôt l’usage de Rustup, le nouveau programme officiel d’installation de Rust (la page officielle de téléchargement commence aussi à y faire référence). Vous trouvez la procédure d’installation sur le site <a rel="noopener" target="_blank" href="https://www.rustup.rs">https://www.rustup.rs</a>, à savoir une simple commande à taper dans une console : <code>curl https://sh.rustup.rs -sSf | sh</code>. Vous installez Rustup qui ensuite installe pour vous le compilateur Rust rustc, l’outil de gestion de dépendances et de build cargo, ainsi que le débuggueur ou le formateur de code de la version stable courante de Rust. Vous pourrez très simplement mettre à jour cette version stable avec rustup update quand vous en aurez besoin (toutes les six semaines !) ou bien installer la beta par exemple (rustup install beta).</p>
<p>Précis et efficace ... quand vous avez curl et un interpréteur sh à disposition, ce qui n’est pas le cas par défaut sous Windows. Si vous développez avec Rust sous Windows, vous aurez, tôt ou tard, besoin aussi de Git pour versionner vos fichiers sources. Je vous recommande donc d’installer d’abord l’outillage de Git qui vient avec une ligne de commande assez complète et qui ressemble à ce que vous pourriez obtenir sur un Linux : <a rel="noopener" target="_blank" href="https://git-for-windows.github.io">https://git-for-windows.github.io</a>. Téléchargez l’installeur 32 ou 64 bits selon votre machine, puis lancez la commande d’installation de Rustup dans le shell proposé par Git for Windows.</p>
<p>A la fin de l’installation, en ligne de commande (sous Windows celle de Git for Windows, n’oubliez pas car je ne le répéterai plus :-), tapez :</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>$ rustc --version
</span></code></pre>
<p>Si vous obtenez quelque chose comme <code>rustc 1.10.0 (cfcb716cf 2016-07-03)</code>, le compilateur Rust est opérationnel sur votre poste !</p>
<h2 id="editeur-de-texte-malin-ou-environnement-de-developpement-integre-ide">Editeur de texte malin ou environnement de développement intégré (IDE) ?</h2>
<p>Autant vous le dire d’emblée, les "assistants" de développement Rust sont loin d’être du niveau de ce que l’on peut trouver dans d’autres langages comme Java ou .Net. Il y a encore beaucoup de travail à faire mais on arrive tout même à se créer un environnement acceptable. Personnellement, je travaille avec Sublime Text, complété par quelques plugins qui me permettent d’avoir la coloration syntaxique, le formatage et le linting, une validation moins précise de la syntaxe. Je vous invite à consulter areweideyet.com pour choisir l’environnement le plus adapté à votre contexte : Vim, Emacs, Atom, Visual Studio, Eclipse ... ou simplement, si vous souhaitez aller vite, un éditeur de texte type Notepad++, Geany ou Sublime Text seront suffisants.</p>
<h2 id="calculer-division-reboot">Calculer division : reboot</h2>
<p>Vous souvenez-vous de votre premier programme Rust écrit dans la première partie de ce dossier ? Nous allons le revisiter avec les nouveaux outils dont nous nous sommes dotés, et en particulier cargo. C’est un mix de Maven pour la structure standard des projets Rust, de npm pour la gestion de dépendances ou l’installation d’un programme et de commandes permettant de gérer un projet Rust.</p>
<p>Créons-en un de type "programme Rust" (grâce au paramètre <code>--bin</code>) :</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>$ cargo new --bin division
</span></code></pre>
<p>Avec votre éditeur de texte, copiez-collez le contenu de notre dernier programme dans le fichier src/main.rs du répertoire division créé par Cargo :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">calculer_division</span><span>(</span><span style="color:#bf616a;">x</span><span>: </span><span style="color:#b48ead;">i32</span><span>, </span><span style="color:#bf616a;">y</span><span>: </span><span style="color:#b48ead;">i32</span><span>) -> </span><span style="color:#b48ead;">i32 </span><span>{
</span><span> </span><span style="color:#b48ead;">match</span><span> y {
</span><span> </span><span style="color:#d08770;">0 </span><span>=> panic!("</span><span style="color:#a3be8c;">Division par 0</span><span>"),
</span><span> </span><span style="color:#d08770;">1 </span><span>=> x,
</span><span> _ => x / y
</span><span> }
</span><span>}
</span><span>
</span><span>
</span><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">main</span><span>() {
</span><span>
</span><span> </span><span style="color:#b48ead;">let</span><span> resultat = </span><span style="color:#96b5b4;">calculer_division</span><span>(-</span><span style="color:#d08770;">4</span><span>, </span><span style="color:#d08770;">2</span><span>);
</span><span>
</span><span> println!("</span><span style="color:#a3be8c;">Résultat : </span><span style="color:#d08770;">{}</span><span>", resultat);
</span><span>
</span><span>}
</span></code></pre>
<p>Code complet sur ce Gist : <a rel="noopener" target="_blank" href="https://git.io/vKcsS">https://git.io/vKcsS</a>. Sauvegardez, puis lancez en ligne de commande :</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>$ cargo run
</span><span>
</span><span> Compiling division v0.1.0 (file://.../division)
</span><span>
</span><span> Running `target/debug/division`
</span><span>
</span><span>Résultat : -2
</span></code></pre>
<p>Cargo compile et lance à la suite le programme sans argument. Si vous souhaitez simplement compiler, lancez cargo build et si vous souhaitez lancer le programme vous-même, sachez qu’il se trouve dans le répertoire target/debug :</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>$ ./target/debug/division
</span><span>
</span><span>Résultat : -2
</span></code></pre>
<h2 id="une-api-sure">Une API sûre</h2>
<p>Nous allons variabiliser le numérateur de notre division et le passer en paramètre de la ligne de commande. Explorons l’API de Rust pour ce besoin : lire les arguments en paramètre du programme s’effectue grâce à une fonction du module std::env déclarée comme ceci (Cf. <a rel="noopener" target="_blank" href="https://doc.rust-lang.org/std/env/fn.args.html">https://doc.rust-lang.org/std/env/fn.args.html</a>) :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">pub fn </span><span style="color:#8fa1b3;">args</span><span>() -> Args
</span></code></pre>
<p>La fonction <code>std::env::args()</code> nous renvoie donc une instance de la <em>struct</em> <code>Args</code> (elle-même dans le module <code>std::env</code>), une structure qui va contenir des champs et des méthodes permettant de manipuler les arguments du programme, et ce de manière sûre. Qu’est-ce que cela signifie ? Sûr implique par exemple le bannissement de la "nullité", source de fréquentes erreurs d’exécution (le fameux <em>NullPointerException</em> en Java par exemple). En Rust, toutes les API sont conçues pour renvoyer quelque chose -un résultat ou une erreur- et même "rien" est quelque chose en Rust.</p>
<h2 id="option-some-none"><code>Option</code> - <code>Some</code> - <code>None</code></h2>
<p>Regardons la déclaration de la fonction nth de Args qui va nous permettre de récupérer le nième argument de notre programme. Elle est déclarée comme ceci (la signature est légèrement adaptée pour une compréhension plus aisée) :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">nth</span><span>(&</span><span style="color:#b48ead;">mut </span><span style="color:#bf616a;">self</span><span>, </span><span style="color:#bf616a;">n</span><span>: </span><span style="color:#b48ead;">usize</span><span>) -> Option<String>
</span></code></pre>
<p>Mettons de coté le &mut self, nous y reviendrons par la suite. nth est une fonction qui renvoie un Option de type String. Option est une énumération Rust à deux variantes possibles :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">pub enum </span><span>Option<T> {
</span><span> None,
</span><span> Some(T),
</span><span>}
</span></code></pre>
<p>Si vous substituez le type générique <code>T</code> par <code>String</code>, vous comprenez alors que la méthode <code>nth</code> peut renvoyer soit <code>None</code>, qui signifie qu’il y a pas de valeur à cette position, soit <code>Some(String)</code>, qui signifie qu’il existe une valeur à la position demandée et quelle peut être extraite de la valeur de l’énumération. Ce qui est génial, c’est que ces variantes peuvent être "matchées" (Cf. partie 1 de ce dossier) :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">use </span><span>std::env;
</span><span>
</span><span>...
</span><span>
</span><span style="color:#b48ead;">let</span><span> numerateur = </span><span style="color:#b48ead;">match </span><span>env::args().</span><span style="color:#96b5b4;">nth</span><span>(</span><span style="color:#d08770;">1</span><span>) {
</span><span> Some(argument) => argument,
</span><span> None => panic!("</span><span style="color:#a3be8c;">Argument obligatoire manquant : le numérateur</span><span>")
</span><span>};
</span></code></pre>
<p>Ici, on effectue aussi du pattern matching pour extraire la valeur contenue dans le <code>Some</code>. <code>Some(argument)</code> permet de déclarer la variable argument, affectée à la valeur contenu dans le <code>Some</code>, que l’on peut alors renvoyer (avec un <code>return</code> implicite). On arrête le programme prématurément avec la macro <code>panic!</code> et un message explicite en cas de <code>None</code>.</p>
<p>Enfin, cerise sur le gâteau, comme tout est expression en Rust, on peut affecter directement le retour de notre match à une variable : <code>let numerateur = match env::args() ...</code>.</p>
<p>Notez l’utilisation du module env importé par une ligne en début de programme, <code>use std::env;</code>, à ajouter pour chaque module utilisé dans le programme.</p>
<p>Avec les <code>Option</code> et l’API de Rust, nous avons pu extraire notre paramètre de ligne de commande et l’avons rendu obligatoire. Ce n’est cependant pas suffisant : en effet, la fonction <code>nth</code> renvoie un <code>Option<String></code> dans notre cas, ce qui veut dire que la variable numerateur ci-dessus est de type <code>String</code>, alors que nous attendons un <code>i32</code>. Il faut donc convertir notre valeur.</p>
<h2 id="result-ok-err"><code>Result</code> - <code>Ok</code> - <code>Err</code></h2>
<p>Rust propose une API de conversion de <code>String</code> :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">parse</span><span><F>(&</span><span style="color:#bf616a;">self</span><span>) -> Result<F, </span><span style="color:#b48ead;">F::</span><span>Err> </span><span style="color:#b48ead;">where</span><span> F: FromStr
</span></code></pre>
<p>Prenons quelques instants pour comprendre la signature de cette fonction :</p>
<ul>
<li><code>fn parse</code> : "parse" est le nom de la fonction :-)</li>
<li><code>F</code> : il s’agit d’un type générique, que vous pouvez substituer mentalement par le type que vous voulez obtenir après le parsing de votre <code>String</code>
La définition en est donnée en fin de ligne, <code>where F: FromStr</code>, ce qui signifie que <code>F</code> doit respecter le contrat décrit dans le <em>trait</em> <code>std::str::FromStr</code> (c’est une sorte d’interface)</li>
<li><code>&self</code> : il s’agit de la syntaxe spécifique à Rust qui indique que cette fonction n’est pas statique et qu’elle s’applique sur des instances de l’objet courant (<code>String</code> ici)</li>
<li><code>Result<F, F::Err></code> : le type de retour, encapsulant <code>F</code> et un type d’erreur associée à <code>F</code></li>
</ul>
<p><code>Result</code> est la façon élégante en Rust de gérer les éventuels retours en erreur d’un traitement. Il est décrit comme ceci dans l’API de Rust :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">pub enum </span><span>Result<T, E> {
</span><span> Ok(T),
</span><span> Err(E),
</span><span>}
</span></code></pre>
<p>Un peu comme <code>Option</code> vue précédemment, <code>Result</code> est une énumération à deux variantes, sur lesquelles on pourra <em>matcher</em> :</p>
<ul>
<li><code>Ok</code> est utilisé pour encapsuler le résultat d’un traitement qui s’est bien déroulé</li>
<li><code>Err</code> permet de propager les erreurs de traitement</li>
</ul>
<p>Il n’y a donc pas d’exception en Rust et l’usage des codes retours pour indiquer un résultat de traitement est considéré comme une mauvaise pratique, car non sûre.</p>
<p>Le type <code>i32</code> implémentant bien le <em>trait</em> <code>std::str::FromStr</code>, on pourrait écrire la fonction dédiée au parsing d’une <code>String</code> en <code>i32</code> :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">parse</span><span>(&</span><span style="color:#bf616a;">self</span><span>) -> Result<</span><span style="color:#b48ead;">i32</span><span>, ParseIntError>
</span></code></pre>
<p>L’association de <code>ParseIntError</code> à <code>i32</code> est décrite dans sa documentation (cherchez <code>impl FromStr for i32</code> et juste en dessous le type <code>Err = ParseIntError</code>).</p>
<p>Gardez en tête que c’est une simple vue de l’esprit, car elle est redondante avec la définition de la fonction décrite avec un type générique, mais elle permet de fixer les idées quand on n’est pas encore à l’aise avec la syntaxe de Rust.</p>
<p>Nous pouvons donc convertir notre <code>String</code> numerateur en <code>i32</code> après un <em>matching</em> :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">let</span><span> numerateur = </span><span style="color:#b48ead;">match</span><span> numerateur.parse::<</span><span style="color:#b48ead;">i32</span><span>>() {
</span><span> Ok(numerateur) => numerateur,
</span><span> Err(error) => panic!("</span><span style="color:#a3be8c;">Impossible de convertir notre argument. Raison: {}</span><span>", error)
</span><span>};
</span></code></pre>
<p>Il faut un peu aider le compilateur car il ne peut pas deviner quelle conversion on souhaite appliquer. Pour cela, on utilise la syntaxe <em>turbofish</em>: <code>::<></code>, qui permet de spécifier le type de destination.</p>
<p>Si le <code>parse</code> s’est bien déroulé, le matching sur <code>Ok</code> permet d’extraire le numérateur sous forme de <code>i32</code> désormais ; sinon avec le matching sur <code>Err</code>, on arrête une nouvelle fois le programme avec un message d’erreur adéquat.</p>
<p>Enfin, substituez le premier paramètre de l’appel de la fonction calculer_division par la variable numerateur (code complet : <a rel="noopener" target="_blank" href="https://git.io/v6ypr">https://git.io/v6ypr</a>), compilez et exécutez en une fois :</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>$ cargo run 4
</span><span>
</span><span> Compiling division v0.1.0 (file://.../division)
</span><span>
</span><span> Running `target/debug/division 4`
</span><span>
</span><span>Résultat : 2
</span></code></pre>
<p>Bravo, en quelques lignes de code robustes, vous avez gérés la présence et l’absence d’argument lors de l’exécution de notre programme et ce, de manière plutôt élégante.</p>
<p>Ainsi se termine cette 2è partie de notre dossier consacré à Rust. <a href="/introduction-rust-part-3/">Dans la prochaine partie</a>, le niveau de difficulté montera d’un cran : il sera en effet temps de se confronter au <em>borrow checker</em> !</p>
Introduction au langage de programmation Rust - Partie 1
2017-03-09T00:00:00+00:00
2017-03-09T00:00:00+00:00
https://dlecan.com/blog/introduction-rust-part-1/
<blockquote>
<p>Article initialement publié sur <a rel="noopener" target="_blank" href="https://www.technologies-ebusiness.com/langages/introduction-a-rust-partie-1">https://www.technologies-ebusiness.com/langages/introduction-a-rust-partie-1</a></p>
</blockquote>
<p>Rust est un jeune langage qui a pour ambition de se substituer au C/C++ en proposant de nouveaux paradigmes de programmation, une librairie standard de haut niveau et un écosystème riche soutenu par une communauté très active.</p>
<p>Multiplateformes (systèmes d’exploitation ou architectures de processeurs) et pourvu de tous les concepts de programmation attendus pour un langage moderne (programmation orientée "objet", programmation fonctionnelle, facilités à développer des programmes d’exécution concurrente), Rust a beaucoup d’atouts pour séduire.</p>
<p>Au travers de cette série d’articles, nous allons découvrir ensemble ce langage qui me paraît être le plus excitant depuis ces dernières années.</p>
<h2 id="genese">Genèse</h2>
<p>Avant de plonger dans le code, je vous propose de revenir sur les origines du langage. Elles remontent à 2010 : Graydon Hoare, ingénieur chez Mozilla, révèle ses travaux sur Rust. A l’époque, le "marché" des langages informatiques est un peu similaire à aujourd’hui, à savoir une domination de C/C++ et de Java, chacun cantonné à ses domaines de prédilection. En schématisant, Java règne sur l’informatique de "gestion" (systèmes d’information bancaires, assurance ...) ainsi que sur Android, tandis que C/C++ est le choix par défaut de la programmation que je qualifierais de "système" ou "bas niveau" : système d’exploitation, pilotes, informatique embarquée, machines virtuelles (Java lui- même, ou NodeJS par exemple) ...</p>
<p>Quelle caractéristique clivante peut bien isoler à ce point ces deux mondes de l’informatique ? Je pense qu’il s’agit principalement de la gestion de la mémoire, qui diverge totalement. Avec Java, elle est en grande partie masquée au développeur, c’est-à-dire que lorsqu’un développeur crée des objets en mémoire, il n’a pas vraiment à se soucier de son nettoyage. En effet, un processus qui s’exécute en arrière-plan, le ramasse-miette (garbage collector), se charge de détecter les objets qui ne seraient plus utilisés et de les supprimer de la mémoire. Le travail du développeur est donc grandement simplifié et celui-ci peut se concentrer sur le code métier le plus utile. C’est ce qui explique le succès de tous les langages à machine virtuelle et ramasse-miettes, comme Javascript ou .Net.</p>
<p>Si le fonctionnement du ramasse-miettes n’a pas ou peu de conséquences négatives -largement compensées par d’autres avantages- dans les applications de haut niveau comme celles dédiées au web, il est problématique, voire rédhibitoire pour d’autres. La latence, certes réduite, induite par l’initialisation ou le fonctionnement du ramasse-miettes, ne permet pas de construire des systèmes de plus bas niveau, comme les systèmes d’exploitation, les pilotes, les machines virtuelles elles-mêmes ou encore des programmes en ligne de commandes efficaces ... Dans ces cas, la mémoire doit donc être gérée "à la main".</p>
<p>En C/C++, la responsabilité du cycle de vie des structures ou objets en mémoire incombe au développeur et gare à la qualité du logiciel si cette tâche est mal effectuée : corruption de données, plantages, failles de sécurité ... sont les conséquences principales d’une mauvaise gestion de la mémoire, phénomène encore aggravé dans un contexte de programme à exécution concurrente. Ne jetons pas la pierre aux développeurs : c’est une tâche ingrate, pénible et peu outillée. Alors dans ces conditions, comment produire des logiciels bas niveau de qualité ?</p>
<p>Depuis les premières ébauches, c’est précisément l’un des objectifs du langages Rust. Il ne repose ni sur un ramasse-miettes (ex: Java), ni sur une gestion mémoire manuelle du développeur (ex: C/C++). Rust propose une nouvelle façon de gérer la mémoire, qui se veut sûre et garantie à la compilation, ce qui permet d’en limiter l’impact sur les performances à l’exécution. Autant vous prévenir tout de suite : la courbe d’apprentissage de Rust est donc plus lente que dans d’autres langages mais largement compensée en qualité et fiabilité des programmes produits. Concrètement, vous allez transpirer au début mais serez fiers de la qualité de vos productions. Nous verrons par la suite comment elle se concrétise.</p>
<p>La syntaxe du langage, ainsi que la librairie standard, ont été débattues, testées, amendées par la -déjà très active- communauté, pendant des années, la première version stable 1.0 de Rust ayant été publiée en avril 2015. Ce délai a permis aussi de mettre en place une gouvernance ouverte et transparente qui régit l’évolution du langage, à laquelle chacun peut participer (board central, RFC ouvertes ...). Trois channels de Rust sont édités en parallèle : nightly, beta et stable. De nouvelles versions de Rust stable et beta sont publiées toutes les 6 semaines, apportant à chaque fois leurs lots d’évolutions au langage.</p>
<p>Avant de démarrer, soyez attentifs lors de vos recherches sur Internet à la version de Rust concernée par les articles de blogs ou les solutions apportées sur Stack Overflow. On y trouve en effet beaucoup de contenus obsolètes, car applicables à des versions de Rust antérieures à la version 1.0.</p>
<p>Enfin, un mot sur la communauté de développeurs Rust. Elle est accueillante et bienveillante, vous trouverez de nombreux développeurs prêts à vous aider, à vous faire progresser ainsi qu’à critiquer votre code de manière constructive. Une bonne surprise et une des forces de ce langage.</p>
<h2 id="bonjour-lecteurs">Bonjour lecteurs !</h2>
<p>Commençons à écrire quelques lignes de code, sans installation préalable de Rust sur votre poste. Rendez-vous sur <a rel="noopener" target="_blank" href="https://play.rust-lang.org/">https://play.rust-lang.org/</a> pour ouvrir l’interpréteur web Rust, qui fonctionne très bien sur smartphone ou tablette. Idéal pour tester simplement Rust sans vous prendre la tête ! Ne modifiez pas le paramétrage par défaut de la page (boutons du haut) et concentrez-vous sur la zone de texte centrale : c’est là qu’il faut taper le code Rust.</p>
<p>Lors de votre première connexion, le formulaire est déjà préinitialisé avec un morceau de code que je vous propose de substituer par un contenu plus adapté à notre contexte :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">main</span><span>() {
</span><span>
</span><span> println!("</span><span style="color:#d08770;">{}</span><span>", "</span><span style="color:#a3be8c;">Bonjour Programmez!</span><span>");
</span><span>}
</span></code></pre>
<p>Si vous avez des difficultés à saisir ce code, vous pouvez ouvrir directement cette URL : https://is.gd/JzBaCy. Par la suite, je présenterai systématiquement un lien vers le code présenté, vous permettant éventuellement de le copier/coller.</p>
<p>Cliquez ensuite sur le gros bouton rouge "Run" en haut pour exécuter ce programme. Vous devez alors obtenir sous la zone de texte de code l’affichage de "Bonjour Programmez!". Bravo, vous venez d’écrire votre premier programme Rust !</p>
<h2 id="analysons-ensemble-ces-quelques-lignes">Analysons ensemble ces quelques lignes</h2>
<p>La syntaxe s’inspire fortement du langage C (que l’on retrouve en Java, Javascript, .Net ...) et le formatage du code est standardisé par le langage : indentation, espaces, positions des accolades ... Notez le bouton "Format" dans l’interpréteur Web qui formate le code de la zone de texte comme on peut s’y attendre 🙂</p>
<ul>
<li><code>fn</code> permet de déclarer une fonction, nommée ici main et sans argument. Par convention, c’est le point d’entrée unique d’un programme écrit en Rust</li>
<li><code>println!</code> permet d’écrire dans la sortie standard, du texte ou des structures plus complexes. Notez le <code>!</code> qui signifie que <code>println!</code> est une macro. C’est une routine de génération de code <strong>à la compilation</strong> et un pattern de développement très utilisé par les développeurs Rust pour masquer une complexité</li>
</ul>
<p>Je vous recommande l’utilisation de <code>println!</code> à deux arguments et plus, syntaxe familière à ceux qui connaissent les fonctions <code>printf/fprintf</code> du C ou <code>str.format</code> de Python : le 1er paramètre représente la mise en forme, les suivants les valeurs à substituer aux <code>{}</code> présents dans le contenu du 1er argument (plus de détails sur <a rel="noopener" target="_blank" href="https://doc.rust-lang.org/std/fmt/">https://doc.rust-lang.org/std/fmt/</a>)</p>
<ul>
<li><code>;</code> obligatoire en fin de ligne la plupart du temps en Rust</li>
</ul>
<p>Modifions maintenant notre programme en déclarant une variable (<a rel="noopener" target="_blank" href="https://is.gd/SIDHI3">https://is.gd/SIDHI3</a>) :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">main</span><span>() {
</span><span> </span><span style="color:#b48ead;">let</span><span> une_chaine = "</span><span style="color:#a3be8c;">Bonjour Programmez!</span><span>";
</span><span> println!("</span><span style="color:#d08770;">{}</span><span>", une_chaine);
</span><span>}
</span></code></pre>
<p>Les variables se déclarent avec le mot-clé <code>let</code>, sont immuables (que l’on ne peut pas réaffecter) et sont fortement typées. Pourtant vous remarquerez que nous n’avons pas déclaré le type de cette variable. En effet, Rust met en œuvre de l’inférence de type, à savoir qu’il tente de détecter le type des variables mais pas des paramètres. Un allègement significatif de la syntaxe qui facilite l’écriture et la relecture. Il faudra cependant parfois l’aider à deviner correctement le type. Remarquez enfin la syntaxe de type <em>snake case</em>, avec des <code>_</code> pour séparer les concepts dans les noms des variables (par opposition à la syntaxe <em>camel case</em>: <code>uneVariable</code>). Pratique, car le compilateur râlera si vous ne respectez pas cette convention.</p>
<p>Lancez avec "Run" pour compiler et exécuter ce code.</p>
<p>Poursuivons la découverte des concepts de Rust en introduisant une nouvelle fonction qui permet d’effectuer la division d’un nombre par un autre :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">calculer_division</span><span>(</span><span style="color:#bf616a;">x</span><span>: </span><span style="color:#b48ead;">i32</span><span>, </span><span style="color:#bf616a;">y</span><span>: </span><span style="color:#b48ead;">i32</span><span>) -> </span><span style="color:#b48ead;">i32 </span><span>{
</span><span> println!("</span><span style="color:#a3be8c;">Numérateur: </span><span style="color:#d08770;">{}</span><span>", x);
</span><span> println!("</span><span style="color:#a3be8c;">Dénominateur: </span><span style="color:#d08770;">{}</span><span>", y);
</span><span> x / y
</span><span>}
</span></code></pre>
<p>L’appel de la fonction que nous venons de déclarer s’effectue exactement comme l’on s’y attend (programme complet : <a rel="noopener" target="_blank" href="https://is.gd/0U61pa">https://is.gd/0U61pa</a>) :</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span>...
</span><span>
</span><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">main</span><span>() {
</span><span> </span><span style="color:#b48ead;">let</span><span> resultat = </span><span style="color:#96b5b4;">calculer_division</span><span>(-</span><span style="color:#d08770;">4</span><span>, </span><span style="color:#d08770;">2</span><span>);
</span><span> println!("</span><span style="color:#a3be8c;">Résultat : </span><span style="color:#d08770;">{}</span><span>", resultat);
</span><span>}
</span></code></pre>
<p>Par choix, il n’y a pas d’inférence de type en Rust lors de la déclaration des fonctions : les types des paramètres d’entrée et du retour doivent être explicitement spécifiés. Le type des arguments est indiqué après chaque nom de variable suivi de : et le type de retour est spécifié après la flèche <code>-></code>. Rust propose une liste de types primitifs très complète, puisque vous avez par exemple la possibilité de choisir des entiers, des flottants signés ou non signés, des entiers ou des flottants de "longueur" variable.</p>
<p>Exemples :</p>
<ul>
<li>
<p><code>u8</code> : est un nombre de longueur 8 octets uniquement positif, donc un nombre compris entre 0 et 255 (2⁸-1)</p>
</li>
<li>
<p><code>i16</code> : est un nombre de longueur 16 octets, positif ou négatif, donc un nombre compris entre -32 768 (-2^16/2) et 32 767 (2^16/2-1)</p>
</li>
</ul>
<p>Je vous conseille d’explorer la liste complète des types primitifs pour vous faire une idée des autres types disponibles (<a rel="noopener" target="_blank" href="https://doc.rust-lang.org/book/primitive-types.html">https://doc.rust-lang.org/book/primitive-types.html</a>).</p>
<p>Les plus attentifs d’entre vous aurons remarqué que cette fonction ne "retourne" explicitement rien comparé à d’autres langages et que la dernière ligne ne se termine pas par un point-virgule, alors que l’on a précédemment vu qu’il était obligatoire. En Rust, il y a un return implicite sur la dernière expression exécutée d’une fonction. Attention, ce n’est pas nécessairement la dernière ligne de code de la fonction. Dans l’exemple ci-dessous, il y a 2 façons de sortir de la fonction et aucune d’entre elles ne correspond à la dernière ligne de code de la fonction.</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">calculer_division</span><span>(</span><span style="color:#bf616a;">x</span><span>: </span><span style="color:#b48ead;">i32</span><span>, </span><span style="color:#bf616a;">y</span><span>: </span><span style="color:#b48ead;">i32</span><span>) -> </span><span style="color:#b48ead;">i32 </span><span>{
</span><span> </span><span style="color:#b48ead;">if</span><span> y != </span><span style="color:#d08770;">0 </span><span>{
</span><span> x / y
</span><span> } </span><span style="color:#b48ead;">else </span><span>{
</span><span> panic!("</span><span style="color:#a3be8c;">Division par 0</span><span>")
</span><span> }
</span><span>}
</span><span>
</span><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">main</span><span>() {
</span><span>...
</span><span>}
</span></code></pre>
<p>Exemple complet : <a rel="noopener" target="_blank" href="https://is.gd/9LKj2d">https://is.gd/9LKj2d</a>.</p>
<p>A propos du point-virgule, dans notre cas ici qui semble manquant, vous ne devez pas en mettre en fin de ligne. Essayez, vous aurez une erreur de compilation ! Pourquoi ? Rust est un langage basé sur les expressions et non sur des déclarations. Cela signifie que tout renvoie quelque chose : assigner une variable renvoie quelque chose, if renvoie quelque chose ... L’expression <code>x / y</code> renvoie le résultat de la division, compatible avec le type <code>i32</code>, là où l’expression <code>x / y;</code> un résultat dont le type est <code>()</code>, incompatible avec <code>i32</code>.</p>
<p>Enfin, modifions une dernière fois notre programme pour induire une syntaxe plus habituelle pour les Rustacéens (traduction de *Rustaceans", le nom officiel des développeurs Rust) : le <em>matching</em>.</p>
<pre data-lang="rust" style="background-color:#2b303b;color:#c0c5ce;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">calculer_division</span><span>(</span><span style="color:#bf616a;">x</span><span>: </span><span style="color:#b48ead;">i32</span><span>, </span><span style="color:#bf616a;">y</span><span>: </span><span style="color:#b48ead;">i32</span><span>) -> </span><span style="color:#b48ead;">i32 </span><span>{
</span><span> </span><span style="color:#b48ead;">match</span><span> y {
</span><span> </span><span style="color:#d08770;">0 </span><span>=> panic!("</span><span style="color:#a3be8c;">Division par 0</span><span>"),
</span><span> </span><span style="color:#d08770;">1 </span><span>=> x,
</span><span> _ => x / y
</span><span> }
</span><span>}
</span><span>
</span><span style="color:#b48ead;">fn </span><span style="color:#8fa1b3;">main</span><span>() {
</span><span>...
</span><span>}
</span></code></pre>
<p>Exemple complet : <a rel="noopener" target="_blank" href="https://is.gd/X7889d">https://is.gd/X7889d</a>.</p>
<p>La syntaxe parle d’elle-même, c’est simple à comprendre. Le <code>match</code> permet de gérer plus de cas que ne peut le faire un simple if tout en rendant obligatoire le traitement du cas par défaut. Qui n’a jamais oublié un else ou un case default en Java, par exemple ? En Rust, c’est impossible car le compilateur s’assure que tous les cas possibles de matching sont bien déclarés et gérés par le développeur. <code>_</code> signifie au compilateur "tous les autres cas de matching" (dans notre cas, "tout sauf 0 et 1"). Sachez aussi que le matching offre aussi beaucoup plus de possibilités que ne montre ce simple exemple.</p>
<p>Ici se termine la 1ère partie de cette introduction à Rust. Je vous invite à poursuivre la lecture de ce dossier avec <a href="/introduction-rust-part-2/">la seconde partie</a>, dans laquelle vous installerez Rust et ses outils sur votre poste de développement et découvrirez d’autres concepts passionnants du langage, avec quelques notions de programmation fonctionnelle.</p>
How to configure Docker DNS on Ubuntu in a corporate environment?
2016-11-24T00:00:00+00:00
2016-11-24T00:00:00+00:00
https://dlecan.com/blog/how-to-configure-docker-dns-on-ubuntu-in-a-corporate-environment/
<p>When you are in a corporate environment, network is often configured to restrict outgoing requests, such as DNS resolution requests. By default, Docker uses Google DNS (8.8.8.8 and 8.8.4.4) to resolve domain names:</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>$ docker run busybox nslookup google.com
</span><span>Server: 8.8.8.8
</span><span>Address 1: 8.8.8.8
</span><span>nslookup: can't resolve 'google.com'
</span></code></pre>
<p>If you are in a corporate environment, resolution fails because you have to use your internal DNS server.</p>
<p>You can find many, many documentation about how to configure Docker DNS on Ubuntu (such as official <a rel="noopener" target="_blank" href="https://docs.docker.com/engine/installation/linux/ubuntulinux/#/configure-a-dns-server-for-use-by-docker">Docker doc</a>), but none of them answer these requirements all together:</p>
<p>1/ Configuration must be portable: works at home or at work or anywhere else</p>
<p>2/ Configuration must be written in files not provided by a deb package to avoid conflicts after package updates</p>
<h2 id="portable-configuration">Portable configuration</h2>
<p>Ubuntu provides Dnsmasq, a local DNS server configured to use DNS server of your network through DHCP. Docker can't use it because it doesn't allow to use a local DNS server if its IP address is a local configuration, such as <code>127.0.0.1</code>.</p>
<p>So we'll configure Dnsmasq to listen to another available IP address, such as the one provided by <code>docker0</code> interface, to solve this issue.</p>
<p>Edit the new file <code>/etc/NetworkManager/dnsmasq.d/docker.conf</code> (as sudo):</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>interface=docker0
</span></code></pre>
<p>Then restart NetworkManager service:</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>sudo service network-manager restart
</span></code></pre>
<h2 id="configure-docker-dns">Configure Docker DNS</h2>
<p>Extract the IP address of the <code>docker0</code> interface:</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>$ docker network inspect bridge | grep Gateway
</span><span> "Gateway": "172.17.0.1"
</span></code></pre>
<p>Then edit <code>/etc/docker/daemon.json</code> (as sudo):</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>{
</span><span> "dns": ["172.17.0.1"]
</span><span>}
</span></code></pre>
<p>Restart Docker:</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>sudo service docker restart
</span></code></pre>
<p>Finally, check DNS resolution works again:</p>
<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>$ docker run busybox nslookup google.com
</span><span>Server: 172.17.0.1
</span><span>Address 1: 172.17.0.1
</span><span>Name: google.com
</span><span>Address 1: 2a00:1450:4009:811::200e lhr26s02-in-x200e.1e100.net
</span><span>Address 2: 216.58.198.174 lhr25s10-in-f14.1e100.net
</span></code></pre>
'Du SSL gratuit pour tous' au Web2Day 2016
2016-06-17T00:00:00+00:00
2016-06-17T00:00:00+00:00
https://dlecan.com/blog/web2day-ssl-gratuit-pour-tous/
<p>J'ai été retenu par la prestigieuse conférence <a rel="noopener" target="_blank" href="https://web2day.co">Web2Day</a> à Nantes pour présenter <a rel="noopener" target="_blank" href="https://web2day.co/2016/evenements/du-ssl-gratuit-pour-tous/">"Du SSL gratuit pour tous"</a> en juin 2016.</p>
<span id="continue-reading"></span>
<p>Dans cette conférence, je démontre comment configurer du TLS/SSL sur votre site web très facilement à l'aide de la nouvelle autorité de certification <a rel="noopener" target="_blank" href="https://letsencrypt.org/">Let's Encrypt</a>.
Elle délivre gratuitement des certificats.</p>
<p>Merci !</p>
<p>Les support de présentation :</p>
<p><a rel="noopener" target="_blank" href="http://dlecan.github.io/web2day2016-ssl-simple-gratuit-avec-lets-encrypt/"><img src="cover.png" alt="Support de présentation de la conférence" /></a></p>
Le Web sécurisé par défaut grâce à DevOps et Let's Encrypt ?
2016-05-25T00:00:00+00:00
2016-05-25T00:00:00+00:00
https://dlecan.com/blog/le-web-securise-par-defaut-grace-a-devops-et-let-s-encrypt/
<p><em><a rel="noopener" target="_blank" href="http://www.journaldunet.com/solutions/expert/64185/le-web-securise-par-defaut-grace-a-devops-et-let-s-encrypt.shtml">Initialement publié sur le Journal Du Net</a></em>.</p>
<p><strong>L'accès à de nombreux sites Web n'est pas sécurisé pour plusieurs raisons : c'est compliqué et cher. Voyons comment les principes du DevOps et un coup de pouce de Let's Encrypt pourraient nous conduire au Web sécurisé par défaut.</strong></p>
<p>Les principes du DevOps insistent fortement sur l'automatisation des processus de construction ou de déploiement des systèmes informatiques. De nombreuses entreprises se sont emparées de ces nouveaux outils et les mettent en œuvre progressivement afin de livrer plus vite, au meilleur coût, avec une qualité élevée, des fonctionnalités à forte valeur ajoutée à leurs clients et leurs utilisateurs.</p>
<p>La plupart des étapes du processus de construction des systèmes informatique sont en effet automatisables : construction et paramétrage des serveurs, construction des applications (serveur ou mobiles), exécution des tests, livraison, déploiement, gestion et prise en compte des pannes... La liste est chaque jour plus longue. Il reste pourtant un domaine où l'automatisation est faible voire inexistante : la sécurité de l'accès aux sites Internet. Or, le contexte actuel d'(in)sécurité du Web en général montre que la sécurité ne doit plus être sacrifiée sur l'autel de la complexité ou du prix.</p>
<h2 id="la-securite-du-web">La sécurité du Web</h2>
<p>Cette sécurité repose sur des protocoles comme HTTPS, TLS, des algorithmes de chiffrement ou de hashage et au cœur, des certificats X.509. La combinaison de ces éléments nous permet d'accéder à des sites Internet de manière sécurisée (httpS://...), nous garantissant des échanges de données chiffrées et donc illisibles pour tout tiers qui tenterait d'intercepter les données. Du moins, en théorie car les failles de sécurités des systèmes informatiques et le talent des pirates leur permettent quelquefois d'accéder à des données confidentielles.</p>
<p>En pratique, la sécurité repose sur d'autres concepts qui permettent de renforcer la sécurité et de limiter les risques de piratage mais l'essentiel du processus repose sur les certificats de la norme X.509.</p>
<h2 id="normes-certes-mais-compliques-et-chers">Normés certes, mais compliqués et chers</h2>
<p><a rel="noopener" target="_blank" href="https://fr.wikipedia.org/wiki/X.509">X.509</a> est une norme qui définit entre autres les fameux certificats sur lesquels reposent HTTPS et TLS. Une chaine de confiance hiérarchique est établie, dans laquelle des certificats particuliers -dits "racine"- signent et valident d'autres certificats. Les certificats racines sont gérés par des autorités de certification qui sont responsables de l'émission de nouveaux certificats.</p>
<p>Les certificats racines sont directement embarqués dans les navigateurs web, ce qui permet à ces derniers d'ouvrir des connexions sécurisées avec des sites web lorsqu'ils présentent un certificat délivré par une autorités de certification reconnue.</p>
<p><em>Les certificats X.509 sont de bons concepts cryptographiques, qui présentent cependant des inconvénients majeurs.</em></p>
<p>1/ Ils sont compliqués à gérer. Un certificat doit être d'abord généré, ce qui requiert plusieurs étapes et fait intervenir plusieurs acteurs. L'utilisateur émetteur doit générer une demande de signature de certificat (CSR) lors de laquelle il choisit un certain nombre de paramètres, tels que la taille de la clé du certificat (il faut se tenir au courant des valeurs assurant un niveau de sécurité adéquat, ce qui évolue avec le temps) et un mot de passe optionnel qui sera requit à chaque usage du certificat. Puis l'autorité de certification doit signer la demande et renvoyer le certificat à l'émetteur de la demande. Enfin, il faut configurer le site web avec le certificat reçu de l'autorité et d'autres paramètres, ce qui est tout sauf évident : les serveurs web ne proposant que rarement une configuration simplifiée (des dizaines de paramètres sont ajustables).</p>
<p>Un certificat a en outre une durée de vie limitée -généralement entre 1 et 3 ans- et doit donc être renouvelé avant son expiration par un processus proche de sa génération initiale. Il faut alors de nouveau mettre à jour la configuration du serveur.</p>
<p>Corollaire direct, gérer les certificats est long et lent. Comme le processus fait intervenir plusieurs acteurs, avec une complexité élevée et d'occurrence rare, pourquoi automatiser quelque chose qui se produit très rarement ? Les certificat sont donc dans la plupart des organisations générés et gérés manuellement et la difficulté est élevée à chaque fois qu'il faut les générer ou renouveler.</p>
<p>2/ Ils sont chers. Demander un certificat à une autorité de certification publique est la plupart du temps payant (jusqu'à plusieurs centaine d'euros par certificat).</p>
<p>Compte tenu de ces inconvénients, le choix des concepteurs de site web est donc radical : ils ne sécurisent pas ou très peu quand ils ne peuvent pas faire autrement. Pourtant, l'accès sécurisé à un site web est désormais essentiel ! <a rel="noopener" target="_blank" href="https://webmasters.googleblog.com/2014/08/https-as-ranking-signal.html">Google favorise et privilégie</a> les sites Internet accessibles au travers de HTTPS en leur offrant un meilleur référencement sur son moteur de recherche. De nouveaux protocoles qui vont apporter de meilleures performances dans les usages mobiles comme HTTP/2, requièrent, aussi, obligatoirement HTTPS, donc TLS, donc des certificats.</p>
<h2 id="des-nouvelles-autorites-de-certification">Des nouvelles autorités de certification</h2>
<p>Revenons à nos pratiques DevOps, et en particulier l'automatisation. Certains acteurs majeurs du Cloud ont bien compris la problématique et proposent depuis quelques temps la gestion complète des certificats, de leur cycle de vie et de leur configuration dans les serveurs web, sans (presque) aucune opération manuelle ! (comme <a rel="noopener" target="_blank" href="https://aws.amazon.com/fr/certificate-manager/">AWS certificate Manager</a>) Une raison de plus pour basculer dans le Cloud !</p>
<p>Pour les autres, une nouvelle autorité de certification répond aux trois problématiques exposées précédemment : Let's Encrypt. Let's Encrypt est une autorité de certification <a rel="noopener" target="_blank" href="https://letsencrypt.org/2016/04/12/leaving-beta-new-sponsors.html">officiellement opérationnelle depuis le 12 avril 2016</a>, avec comme principes clés la gratuité, l'automatisation et la sécurité. Le tout garanti par la transparence et l'ouverture de ses processus et de ses codes sources.</p>
<p>Comme toute autorité de certification, Let's Encrypt délivre des certificats, les renouvelle mais aussi les configure sur les serveurs web, et ce automatiquement, sans autre intervention humaine que de fournir un paramétrage initial. Ensuite, les outils s'occupent de tout ! Et comme un bon processus est un processus récurrent fréquent, Let's Encrypt force à l'automatisation en générant des certificats à durée de vie extrêmement courte : seulement trois mois, avec préconisation de renouvellement au bout de deux mois. Impossible à utiliser sans automatisation donc.</p>
<h2 id="le-web-securise-par-defaut-grace-aux-principes-devops">Le Web sécurisé par défaut grâce aux principes DevOps ?</h2>
<p><a rel="noopener" target="_blank" href="https://letsencrypt.org/sponsors/">De nombreuses entreprises et entités soutiennent Let's Encrypt</a>, financièrement et moralement, comme Mozilla, Akamai, Cisco, OVH, Google, Facebook, Gemalto, Gandi, Free, HP… et l'usage des certificats émis par Let's Encrypt se répand comme une trainée de poudre : <a rel="noopener" target="_blank" href="https://letsencrypt.org/2016/03/08/our-millionth-cert.html">le cap du million de certificats générés</a> a été franchi en mars 2016 et la progression continue sur le même rythme ; de plus en plus de services Internet proposent ou vont proposer très prochainement de sécuriser les sites web de leurs utilisateurs au travers de Let's Encrypt : Gandi, Free/Online, Wordpress, OVH, sans compter divers CDN (KeyCDN, Kloudsec, CDNSun …).</p>
<p>L'usage simplifié promu par Let's Encrypt n'est pas étranger à cette adoption, qui sera sans nul doute, massive dans les années à venir.
En effet, tout le monde y gagne :</p>
<ul>
<li>Les concepteurs de site : activation de la sécurité de manière simple, voire transparente, voire même par défaut ; meilleur référencement auprès de Google,</li>
<li>Les utilisateurs : garantie de confidentialité de leurs activités sur de nombreux sites web ; en ce temps d'espionnage massif, c'est essentiel pour garantir la confiance,</li>
<li>Les services Internet d'hébergement de sites ou les CDN : c'est un service gratuit de plus à offrir à leur client et qui peut en attirer de nouveaux.</li>
</ul>
<p>Les autorités de certification traditionnelles sont pour le moment relativement épargnées puisque que ce sont principalement des sites web qui n'étaient pas auparavant sécurisés qui basculent vers Let's Encrypt. De plus, certains types de certificats ne sont actuellement pas pris en compte par Let's Encrypt, ce qui continue de garantir leur monopole. Mais pour combien de temps ?</p>
<p><a rel="noopener" target="_blank" href="https://blog.imirhil.fr/2015/12/12/letsencrypt-joie-deception.html">Certains considèrent cependant</a> que les choix effectués par Let's Encrypt vont à l'encontre de l'élévation du niveau de sécurité des sites web. Mais ce sont justement ces choix qui permettent et conduisent à l'automatisation. Le web sécurisé par défaut n'a jamais été aussi proche grâce aux principes DevOps et à Let's Encrypt.</p>
Tool In Action 'Sécuriser vos applications Web gratuitement' à Devoxx 2016
2016-04-21T00:00:00+00:00
2016-04-21T00:00:00+00:00
https://dlecan.com/blog/devoxx-securiser-web/
<p>J'ai été retenu par la prestigieuse conférence <a rel="noopener" target="_blank" href="https://devoxx.fr">Devoxx FR</a> pour démontrer les capacité de <a rel="noopener" target="_blank" href="https://letsencrypt.org/">Let's Encrypt</a> lors d'un <em>tool in action</em> en avril 2016.</p>
<span id="continue-reading"></span>
<p>Dans cette conférence <a rel="noopener" target="_blank" href="http://cfp.devoxx.fr/2016/talk/WFF-3798/Securisez_vos_applications_Web_gratuitement_en_quelques_minutes_avec_Let's_Encrypt.html">"Sécurisez vos applications Web gratuitement en quelques minutes avec Let's Encrypt"</a>, je démontre comment configurer du TLS/SSL sur votre site web très facilement à l'aide de cette nouvelle autorité de certification.</p>
<p>Elle délivre en effet gratuitement des certificats.</p>
<p>Merci !</p>
<p>La vidéo de la session :</p>
<div class="youtube is-flex is-justify-content-center is-align-items-center">
<iframe
width="848" height="510"
src="https://www.youtube.com/embed/hD4923vHXsY"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>
Redeemable promises avec Play Framework
2014-11-15T00:00:00+00:00
2014-11-15T00:00:00+00:00
https://dlecan.com/blog/redeemable-promises-avec-play-framework/
<p>J'ai eu à intervenir récemment sur un programme écrit en Play Framework v2.3, dont le rôle est assez simple : faire passe-plat entre un client et un serveur et effectuant notamment des transformations protocolaires (comme REST vers TCP par exemple). Ce qui m'a donné l'occasion d'utiliser les <a rel="noopener" target="_blank" href="https://www.playframework.com/documentation/2.4.x/api/java/play/libs/F.RedeemablePromise.html">RedeemablePromise</a> de Play Framework, pas du tout documentées à ce jour.</p>
<h2 id="client-asynchrone">Client asynchrone</h2>
<p>Les différents échanges de messages entre les systèmes peuvent être représentés à l'aide du diagramme de séquence suivant :</p>
<!--
http://www.websequencediagrams.com/?lz=dGl0bGUgQ2xpZW50IGFzeW5jaHJvbmUKCgANBi0-UGFzc2VQbGF0OlBPU1QgbWVzc2FnZQoADgktPlNlcnZldXI6c2VuZAAXCQAOBy0ANQwgYWNrAC4LLT4AcQY6IDIwMAAXBQpub3RlIG92ZXIAgQsHLAB1CSwAXgggUGx1cyB0YXJkLCB1bgCBCAggZGUgcmV0b3VyCgByCQBuDHJlc3BvbnMAgSsNAHYIAIFTBQAYCQCBcQcAgSsNAIEYCACBMAwAgQcJYWNr&s=modern-blue
-->
<p><img src="http://www.websequencediagrams.com/cgi-bin/cdraw?lz=dGl0bGUgQ2xpZW50IGFzeW5jaHJvbmUKCgANBi0-UGFzc2VQbGF0OlBPU1QgbWVzc2FnZQoADgktPlNlcnZldXI6c2VuZAAXCQAOBy0ANQwgYWNrAC4LLT4AcQY6IDIwMAAXBQpub3RlIG92ZXIAgQsHLAB1CSwAXgggUGx1cyB0YXJkLCB1bgCBCAggZGUgcmV0b3VyCgByCQBuDHJlc3BvbnMAgSsNAHYIAIFTBQAYCQCBcQcAgSsNAIEYCACBMAwAgQcJYWNr&s=modern-blue" alt="Diagram" /></p>
<p>Le programme en Play Framework est nommé "PassePlat" dans ce diagramme.</p>
<p>Les messages montants sont implémentés sous forme d'une API RESTful ; tandis que le retour du "Serveur", asynchrone, est implémentée avec des <em>callbacks</em> et une requête REST vers le client d'origine.</p>
<p>Voici un exemple de pseudo-code Java sur le traitement du message de retour :</p>
<pre data-lang="java" style="background-color:#2b303b;color:#c0c5ce;" class="language-java "><code class="language-java" data-lang="java"><span style="color:#b48ead;">public class </span><span style="color:#ebcb8b;">ServerReceiver </span><span style="color:#eff1f5;">{
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">public void </span><span style="color:#8fa1b3;">onServerResponse</span><span style="color:#eff1f5;">(</span><span style="color:#ebcb8b;">Response </span><span style="color:#bf616a;">response</span><span style="color:#eff1f5;">) {
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Utilisation de la librairie play.libs.ws.WS
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// pour effectuer des appels REST
</span><span style="color:#eff1f5;"> </span><span style="color:#d08770;">WS</span><span style="color:#eff1f5;">.</span><span style="color:#bf616a;">url</span><span style="color:#eff1f5;">(</span><span>"</span><span style="color:#a3be8c;">http://client_url/api/response</span><span>"</span><span style="color:#eff1f5;">)
</span><span style="color:#eff1f5;"> .</span><span style="color:#bf616a;">setContentType</span><span style="color:#eff1f5;">(</span><span>"</span><span style="color:#a3be8c;">application/json</span><span>"</span><span style="color:#eff1f5;">)
</span><span style="color:#eff1f5;"> .</span><span style="color:#bf616a;">post</span><span style="color:#eff1f5;">(response.</span><span style="color:#bf616a;">asJson</span><span style="color:#eff1f5;">());
</span><span style="color:#eff1f5;"> }
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">public void </span><span style="color:#8fa1b3;">onServerError</span><span style="color:#eff1f5;">(</span><span style="color:#ebcb8b;">Throwable </span><span style="color:#bf616a;">error</span><span style="color:#eff1f5;">) {
</span><span style="color:#eff1f5;"> </span><span style="color:#d08770;">WS</span><span style="color:#eff1f5;">.</span><span style="color:#bf616a;">url</span><span style="color:#eff1f5;">(</span><span>"</span><span style="color:#a3be8c;">http://client_url/api/response</span><span>"</span><span style="color:#eff1f5;">)
</span><span style="color:#eff1f5;"> .</span><span style="color:#bf616a;">setContentType</span><span style="color:#eff1f5;">(</span><span>"</span><span style="color:#a3be8c;">application/json</span><span>"</span><span style="color:#eff1f5;">)
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Serialize exception as JSON
</span><span style="color:#eff1f5;"> .</span><span style="color:#bf616a;">post</span><span style="color:#eff1f5;">(</span><span style="color:#ebcb8b;">Helper</span><span style="color:#eff1f5;">.</span><span style="color:#bf616a;">asJson</span><span style="color:#eff1f5;">(error)</span><span style="background-color:#bf616a;color:#2b303b;">;</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> }
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;">}
</span></code></pre>
<p>Le système complet fonctionne bien, mais n'est pas très satisfaisant :</p>
<ul>
<li>
<p>le Client et le PassePlat sont très couplés. En effet, le Client doit connaître l'adresse du PassePlat pour lui envoyer les messages montants et le PassePlat doit connaitre l'adresse du Client pour lui renvoyer le message de retour. Bref, une dépendance cyclique ;</p>
</li>
<li>
<p>Le fonctionnement du Serveur est asynchrone (messages montants et de retours sont décorrélés) et cette implémentation a déporté l'asynchronisme jusqu'au Client, alors que le client (l'humain cette fois-ci :-) voulait plutôt un fonctionnement synchrone du Client, ce qui était plus facile à appréhender pour lui.</p>
</li>
</ul>
<h2 id="client-synchrone">Client synchrone</h2>
<p>Nous avons donc travaillés sur une implémentation du système plutôt comme ceci :</p>
<!--
http://www.websequencediagrams.com/?lz=dGl0bGUgQ2xpZW50IHN5bmNocm9uZQoKAAwGLT5QYXNzZVBsYXQ6UE9TVCBtZXNzYWdlCgAOCS0-U2VydmV1cjpzZW5kABcJAA4HLQA1DCBhY2sKCm5vdGUgb3ZlcgBuBywAWQksAEIIIFBsdXMgdGFyZCwgdW4AbAggZGUgcmV0b3VyCgBWCQBSDHJlc3BvbnMAgRAMLT4AgVMGOiAyMDAAGAkgKwCBBQUAgTATADsJQWNr&s=modern-blue
-->
<p><img src="http://www.websequencediagrams.com/cgi-bin/cdraw?lz=dGl0bGUgQ2xpZW50IHN5bmNocm9uZQoKAAwGLT5QYXNzZVBsYXQ6UE9TVCBtZXNzYWdlCgAOCS0-U2VydmV1cjpzZW5kABcJAA4HLQA1DCBhY2sKCm5vdGUgb3ZlcgBuBywAWQksAEIIIFBsdXMgdGFyZCwgdW4AbAggZGUgcmV0b3VyCgBWCQBSDHJlc3BvbnMAgRAMLT4AgVMGOiAyMDAAGAkgKwCBBQUAgTATADsJQWNr&s=modern-blue" alt="Diagram" /></p>
<p>L'appel du Client vers le PassePlat est donc bloqué tant que l'acquittement <strong>et</strong> la réponse du Serveur ne sont pas parvenus au PassePlat.</p>
<h3 id="comment">Comment ?</h3>
<p>On peut faire cela très simplement avec les <a rel="noopener" target="_blank" href="https://www.playframework.com/documentation/2.4.x/api/java/play/libs/F.RedeemablePromise.html">RedeemablePromise</a> de Play Framework.</p>
<p>Les <a rel="noopener" target="_blank" href="https://www.playframework.com/documentation/2.4.x/api/java/play/libs/F.RedeemablePromise.html">RedeemablePromise</a> sont une implémentation du design pattern <em>promise</em>, désormais répandu dans l'informatique pour résoudre le <a rel="noopener" target="_blank" href="http://callbackhell.com/"><em>callback hell</em></a> -l'enfer des callbacks-, problème très fréquent avec la programmation asynchrone. En effet, votre code est exécuté au sein de <em>callbacks</em> en réponse à des évènements : fin de traitement, lecture d'un fichier, arrivée d'un message par Web Socket, ...</p>
<p>On trouve des implémentations de ce pattern naturellement en <a rel="noopener" target="_blank" href="https://www.promisejs.org/">Javascript</a> (<a rel="noopener" target="_blank" href="https://docs.angularjs.org/api/ng/service/$q">plusieurs même</a>), mais aussi en <a rel="noopener" target="_blank" href="http://docs.scala-lang.org/overviews/core/futures.html">Scala</a>, en <a rel="noopener" target="_blank" href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html">Java</a>, ...</p>
<p>Voyons comment nous pouvons les utiliser pour répondre à notre nouveau besoin.</p>
<p>Adaptons la classe qui réceptionne les évènements venant du Serveur :</p>
<pre data-lang="java" style="background-color:#2b303b;color:#c0c5ce;" class="language-java "><code class="language-java" data-lang="java"><span style="color:#b48ead;">public class </span><span style="color:#ebcb8b;">ServerReceiver </span><span style="color:#eff1f5;">{
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Initialisation de la promesse, à vide
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">private </span><span style="color:#ebcb8b;">RedeemablePromise</span><span style="color:#eff1f5;"><</span><span style="color:#ebcb8b;">Response</span><span style="color:#eff1f5;">> promise </span><span>= </span><span style="color:#ebcb8b;">RedeemablePromise</span><span style="color:#eff1f5;">.</span><span style="color:#bf616a;">empty</span><span style="color:#eff1f5;">();
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// get/set
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">public void </span><span style="color:#8fa1b3;">onServerResponse</span><span style="color:#eff1f5;">(</span><span style="color:#ebcb8b;">Response </span><span style="color:#bf616a;">response</span><span style="color:#eff1f5;">) {
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// La promesse est résolue ou complétée avec succès ici
</span><span style="color:#eff1f5;"> promise.</span><span style="color:#bf616a;">success</span><span style="color:#eff1f5;">(response);
</span><span style="color:#eff1f5;"> }
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">public void </span><span style="color:#8fa1b3;">onServerError</span><span style="color:#eff1f5;">(</span><span style="color:#ebcb8b;">Throwable </span><span style="color:#bf616a;">error</span><span style="color:#eff1f5;">) {
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// La promesse est résolue ou complétée en erreur avec l'exception
</span><span style="color:#eff1f5;"> promise.</span><span style="color:#bf616a;">failure</span><span style="color:#eff1f5;">(error);
</span><span style="color:#eff1f5;"> }
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;">}
</span></code></pre>
<p>L'élément clé ici est le fait de "résoudre" ou "compléter" la promesse en succès ou en erreur selon le cas. Attention à n'oublier aucun cas de fin de traitement du Serveur, sinon le Client restera bloqué dans ces cas non prévus.</p>
<p>Jetons maintenant un coup d'oeil au contrôleur REST sur le PassePlat qui reçoit les requêtes HTTP depuis le Client et qui "bloque" tant que la réponse du Serveur n'est pas parvenue :</p>
<pre data-lang="java" style="background-color:#2b303b;color:#c0c5ce;" class="language-java "><code class="language-java" data-lang="java"><span style="color:#b48ead;">public static </span><span style="color:#ebcb8b;">Promise</span><span><</span><span style="color:#ebcb8b;">Result</span><span>> </span><span style="color:#bf616a;">sendMessage</span><span>(...) {
</span><span>
</span><span> </span><span style="color:#65737e;">// Envoi du message entrant vers le serveur
</span><span> </span><span style="color:#65737e;">// server.send(message)
</span><span>
</span><span> </span><span style="color:#ebcb8b;">ServerReceiver</span><span> serverReceiver = </span><span style="color:#b48ead;">new </span><span style="color:#ebcb8b;">ServerReceiver</span><span>();
</span><span>
</span><span> </span><span style="color:#65737e;">// Ecoute des messages retour
</span><span> server.</span><span style="color:#bf616a;">listen</span><span>(serverReceiver);
</span><span>
</span><span> </span><span style="color:#b48ead;">return
</span><span> </span><span style="color:#65737e;">// Promesse de type Promise<Response>
</span><span> serverReceiver.</span><span style="color:#bf616a;">getPromise</span><span>()
</span><span> </span><span style="color:#65737e;">// Conversion 'success' en Promise<Result>
</span><span> .</span><span style="color:#bf616a;">map</span><span>(</span><span style="color:#bf616a;">response </span><span style="color:#b48ead;">->
</span><span> </span><span style="color:#bf616a;">ok</span><span>(</span><span style="color:#d08770;">JSON</span><span>.</span><span style="color:#bf616a;">toJson</span><span>(response))</span><span style="background-color:#bf616a;color:#2b303b;">;</span><span>
</span><span> </span><span style="background-color:#bf616a;color:#2b303b;">)</span><span>;
</span><span>}
</span><span>...
</span></code></pre>
<p>Dans le cas nominal, la <code>Response</code> sera convertie en <code>Result</code> au sein de la méthode <code>map</code> (programmation fonctionnelle).</p>
<p>Et dans le cas où la promesse a été résolue en erreur ?
Par défaut, Play va générer une réponse HTTP avec un code retour 500 et une sérialisation de l'exception renvoyée. Si vous souhaitez définir vous-même votre propre retour, il faut que le traitement de l'erreur génère un <code>Result</code> standard.</p>
<p>Voici comment adapter la transformation de la promesse pour renvoyer une erreur 500 et une sérialisation de l'exception en cas de promesse résolue en erreur :</p>
<pre data-lang="java" style="background-color:#2b303b;color:#c0c5ce;" class="language-java "><code class="language-java" data-lang="java"><span style="color:#b48ead;">return
</span><span> </span><span style="color:#65737e;">// Promesse de type Promise<Response>
</span><span> promise
</span><span> </span><span style="color:#65737e;">// Conversion 'success' en Promise<Result>
</span><span> .</span><span style="color:#bf616a;">map</span><span>(</span><span style="color:#bf616a;">response </span><span style="color:#b48ead;">->
</span><span> </span><span style="color:#bf616a;">ok</span><span>(</span><span style="color:#ebcb8b;">Json</span><span>.</span><span style="color:#bf616a;">toJson</span><span>(response))</span><span style="background-color:#bf616a;color:#2b303b;">;</span><span>
</span><span> )
</span><span> </span><span style="color:#65737e;">// Conversion 'failure' en Promise<Result>
</span><span> .</span><span style="color:#bf616a;">recover</span><span>(</span><span style="color:#bf616a;">error </span><span style="color:#b48ead;">->
</span><span> </span><span style="color:#65737e;">// Serialize exception as JSON
</span><span> </span><span style="color:#65737e;">// and send HTTP 500 status
</span><span> </span><span style="color:#bf616a;">internalServerError</span><span>(</span><span style="color:#ebcb8b;">Json</span><span>.</span><span style="color:#bf616a;">toJson</span><span>(error))</span><span style="background-color:#bf616a;color:#2b303b;">;</span><span>
</span><span> );
</span></code></pre>
<p>Au final, nous avons pu rendre l'appel du Client synchrone en à peine quelques lignes de code grâce à l'API riche de Play Framework.
Enfin, vous remarquerez que Java 8 améliore significativement la lisibilité du code. Cependant, on reste loin de Scala, de Groovy ou tout simplement de Javascript.</p>
'Mozilla Geckoview' au Devfest Nantes 2014
2014-11-08T00:00:00+00:00
2014-11-08T00:00:00+00:00
https://dlecan.com/blog/mettez-panda-roux-dans-votre-webview-android/
<p>J'ai eu le plaisir de participer à cette superbe conférence que fut le <a rel="noopener" target="_blank" href="http://devfest.gdgnantes.com/">Devfest Nantes 2014</a>, à la fois en tant que visiteur mais aussi en tant qu'orateur.</p>
<span id="continue-reading"></span>
<p>J'y ai présenté la conférence "Mettez un Panda Roux dans votre Webview", dont voici le résumé :</p>
<blockquote>
<p>Au-delà du simple navigateur pour Android, Firefox est aussi une plateforme d'exécution d'applications HTML5 ouverte, les Open Web Apps.
Après une présentation de Mozilla Geckoview et de ce qu'il peut apporter à vos applications HTML5 sous Android par rapport à une Webview standard (modernité, performances...), nous détaillerons l'initiative de Mozilla avec les Open Web Apps et verrons concrètement comment l'utiliser pour déployer des applications HTML5 sous Android.</p>
</blockquote>
<p>Et le support de présentation :</p>
<p><a rel="noopener" target="_blank" href="http://dlecan.github.io/devfestnantes2014/prez-panda-roux-webview-android/"><img src="cover.png" alt="Support de présentation de la conférence" /></a></p>
<p>La vidéo :</p>
<div class="youtube is-flex is-justify-content-center is-align-items-center">
<iframe
width="848" height="510"
src="https://www.youtube.com/embed/SBzsADcBdBE"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>
'Des libs Android pour un dev carré' au GDG Nantes
2014-06-17T00:00:00+00:00
2014-06-17T00:00:00+00:00
https://dlecan.com/blog/gdgnantes-2014-lib-android/
<p>Le <a rel="noopener" target="_blank" href="http://gdgnantes.com">GDG Nantes</a> m'a invité à venir présenter les fantastiques librairies de développement Android de Square le 16 juin 2014 au soir.</p>
<span id="continue-reading"></span>
<p>Merci pour l'apéro et pour le public !</p>
<p>Support de présentation :</p>
<p><a rel="noopener" target="_blank" href="http://dlecan.github.io/lib-android-dev-carre/prez/"><img src="cover.png" alt="Support de présentation de la conférence" /></a></p>
Versions of FreeFileSync available on Ubuntu via PPA installation
2014-05-18T00:00:00+00:00
2014-05-18T00:00:00+00:00
https://dlecan.com/blog/versions-of-freefilesync-available-on-ubuntu-via-ppa-installation/
<p>Author of <a rel="noopener" target="_blank" href="http://freefilesync.sourceforge.net/">FreeFileSync</a> publishes <a rel="noopener" target="_blank" href="http://www.fosshub.com/FreeFileSync.html">binaries</a> for Ubuntu for each release. But you have to install them again and again, once a month. That's why I am the maintainer of <a rel="noopener" target="_blank" href="https://launchpad.net/%7Efreefilesync/+archive/ffs">FreeFileSync PPA</a>, the way in Ubuntu to distribute binaries with automatic updates.</p>
<p>As of May 2014, here are the FreeFileSync versions available for each Ubuntu series:</p>
<table><thead><tr><th>Ubuntu series</th><th align="center">Last available version of FreeFileSync</th><th align="center">Supported ?</th><th>Comment</th></tr></thead><tbody>
<tr><td>Natty</td><td align="center">4.0</td><td align="center">No</td><td></td></tr>
<tr><td>Oneiric</td><td align="center">5.5</td><td align="center">No</td><td></td></tr>
<tr><td>Precise</td><td align="center">5.21</td><td align="center">No</td><td>Requires newer libraries</td></tr>
<tr><td>Quantal</td><td align="center">5.23</td><td align="center">No</td><td>Requires newer libraries</td></tr>
<tr><td>Raring</td><td align="center">5.23</td><td align="center">No</td><td>Requires newer libraries</td></tr>
<tr><td>Saucy</td><td align="center">6.0</td><td align="center">Could be if asked</td><td></td></tr>
<tr><td>Trusty</td><td align="center">6.5</td><td align="center">Yes</td><td></td></tr>
</tbody></table>
Applications HTML5 sur Android : la solution Geckoview de Mozilla
2013-10-31T00:00:00+00:00
2013-10-31T00:00:00+00:00
https://dlecan.com/blog/applications-html5-android-solution-mozilla-geckoview/
<p>Les applications HTML5 sur mobile ont pour principal avantage une portabilité élevée et donc potentiellement des coûts de développement plus réduits à mesure que le nombre de plateformes à supporter grandit. Comme la présence de ces applications dans les "stores" est un prérequis, une application HTML5 doit donc être "packagée", c'est-à-dire encapsulée dans un lanceur écrit en code natif. Elle est alors exécutée dans ce que l'on appelle une <em>webview</em>, dont on peut paramétrer finement le comportement : activer ou non le zoom, taille du cache HTML5, gestion particulière de la sécurité, ...</p>
<p>Voici une synthèse des <em>webviews</em> disponibles selon les plateformes :</p>
<ul>
<li><strong>Windows 8.x Pro</strong> : IE 10/11 dans un mode d'exécution adapté à une application HTML5</li>
<li><strong>iOS</strong> : Safari, amputé de son moteur d'exécution Javascript performant</li>
<li><strong>Firefox OS</strong> : Firefox dans un mode d'exécution adapté à une application HTML5</li>
<li><strong>Android <= 4.3.x</strong> : un "truc" vaguement basé sur Chromium, le moteur partagé avec Chrome, peu compatible avec HTML5 : WebGL, WebRTC, Websockets, SSE, ... sont manquants</li>
<li><strong>Android >= 4.4</strong> : <a rel="noopener" target="_blank" href="http://developer.android.com/about/versions/kitkat.html#44-webview">une image de Chrome pour Android</a>, mais qui, a priori, se met à jour uniquement avec Android lui-même </li>
</ul>
<h3 id="que-valent-ces-navigateurs">Que valent ces navigateurs ?</h3>
<p>Prenez une application HTML5 qui a été conçue pour se faire passer pour du natif, c'est-à-dire reposant massivement sur des animations, des rotations, des effets de fondus, d'apparition avec dégradés, du défilement infini ... comme j'ai pu en voir une récemment.</p>
<p>Sur iPad 4, les performances du HTML5 sont très proches de celles du natif. Il faut pratiquer longuement les deux versions pour les différencier et se rendre compte petit à petit que la version HTML5 est un peu moins fluide, un peu moins réactive, que quelques animations saccadent, ... Pour cette application, inutile de faire du natif sur cette plateforme. Sur l'iPad 5 Air que je viens de tester, il n'y a plus de différence.</p>
<p>Sur une vraie tablette Windows 8 Lenovo, j'ai été très, mais vraiment très surpris des excellentes performances d'IE10. Elles sont du niveau de celles d'iOS. Les résultats du travail de Microsoft sont là, HTML5 est une plateforme de développement crédible sur Windows 8.</p>
<p>Enfin sur des tablettes Android (Nexus 10, Notes 10.1), ce fut la douche froide : saccades, blocages, disparitions purement et simplement de certaines animations (trop lentes pour être affichées ?), malgré de nombreux efforts pour ajouter des optimisations, des accélérations matérielles, ... sans succès notable. L'application est inutilisable, son ergonomie doit être revue à la baisse pour cette plateforme.</p>
<p>Voici un extrait d'un <a rel="noopener" target="_blank" href="https://code.google.com/p/chromium/issues/detail?id=113088">rapport de bug Android</a> qui résume bien la problématique : </p>
<blockquote>
<p><a rel="noopener" target="_blank" href="http://code.google.com/p/chromium/issues/detail?id=113088#c12">Webview for Android is the Internet Explorer of the mobile world</a> - Jason</p>
</blockquote>
<blockquote>
<p><a rel="noopener" target="_blank" href="http://code.google.com/p/chromium/issues/detail?id=113088#c12">La <em>webview</em> d'Android est l'Internet Explorer du monde mobile</a> - Jason</p>
</blockquote>
<p>En effet, comme Android est aujourd'hui <a rel="noopener" target="_blank" href="http://techcrunch.com/2013/08/07/android-nears-80-market-share-in-global-smartphone-shipments-as-ios-and-blackberry-share-slides-per-idc/">la plateforme mobile dominante sur le marché</a>, une stratégie de développement d'applications "sexies" basée sur HTML5 vous expose donc à l'ire et aux complaintes de vos utilisateurs équipés de terminaux Android. Et même si le moteur de la <em>webview</em> a été mis à jour dans Android 4.4 (très proche de Chrome pour Android), des fonctionnalités importantes de HTML5 ne sont pas encore disponibles (WebGL, WebRTC, ... Websockets ?) et il faudra des années à cette nouvelle version pour être suffisamment déployée.</p>
<p>En 2013, résoudre ce problème sur Android se résume donc très simplement : embarquer un moteur HTML performant directement <strong>dans</strong> les applications HTML5, sous forme d'une librairie statique. Le moteur HTML5 fourni avec la version d'Android livrée avec votre tablette ou votre smartphone ne serait ainsi plus utilisé, remplacé par un Chrome ou un Firefox performant.</p>
<p>Voyons donc les <a rel="noopener" target="_blank" href="https://code.google.com/p/chromium/issues/detail?id=113088#c86">travaux proposées</a> qui me paraissent les plus prometteurs :</p>
<ul>
<li>Chromium/Chrome en tant que nouvelle <em>webview</em>, soit en tant que <a rel="noopener" target="_blank" href="http://code.google.com/p/chromium/issues/detail?id=113088#c100">projet Google</a> ou en tant que <a rel="noopener" target="_blank" href="https://github.com/davisford/chromeview">projet "communautaire"</a></li>
<li>Le projet <a rel="noopener" target="_blank" href="https://wiki.mozilla.org/Mobile/GeckoView">Geckoview</a> de Mozilla</li>
</ul>
<p>C'est surtout le deuxième qui me semble le plus prometteur, parce qu'il ne se restreint pas à la seule plateforme Android. L'ambition de ce projet est de fournir une webview basée sur Firefox pour toutes les plateformes, d'aujourd'hui ou à venir, mobiles ou non "} : Android, Windows, Linux, ... Seul <a rel="noopener" target="_blank" href="https://support.mozilla.org/fr/kb/firefox-disponible-pour-iphone-ipad">iOS fait exception</a> car les restrictions imposées par Apple ne permettent pas de déployer Firefox dans de bonnes conditions. Mais c'est sans conséquence pour une application HTML5, iOS étant une plateforme de choix pour exécuter du HTML5 comme nous l'avons déjà évoqué plus haut. Au prix de 25 Mio (!), Geckoview est compatible avec les versions Android 2.x / 3.x / 4.x et avec toutes les fonctionnalités HTML5 avancées : à vous SSE, websockets, WebGL, ...</p>
<p>Le projet est très actif et il est d'ores et déjà possible de monter des prototypes avec <a rel="noopener" target="_blank" href="https://wiki.mozilla.org/Mobile/GeckoView">le code mis à disposition par l'équipe de développement</a>, qui propose notamment <a rel="noopener" target="_blank" href="https://github.com/mfinkle/geckobrowser">un navigateur basé sur Geckoview</a>. Pour l'avoir déjà mis en oeuvre sur un projet à titre de démonstration, c'est très, très prometteur : sur la fameuse application qui veut se faire passer pour du natif dont je vous ai parlé plus haut, les performances du HTML5 sont très proches de celles du natif !</p>
<h3 id="geckoview-est-il-l-avenir-du-html5-sur-android">Geckoview est-il l'avenir du HTML5 sur Android ?</h3>
<p>Compte-tenu du fait qu'Android 4.4 ne résout que partiellement la problématique, la solution qui consiste à embarquer un nouveau moteur de <em>webview</em> directement dans nos applications HTML5 a de l'avenir.</p>
<p>Et sur ce point, Mozilla est bien parti.</p>
'Papy fait du Scala' au BreizhCamp 2013
2013-06-14T00:00:00+00:00
2013-06-14T00:00:00+00:00
https://dlecan.com/blog/papy-fait-du-scala/
<p>J'ai eu le plaisir de participer au <a rel="noopener" target="_blank" href="http://2013.breizhcamp.org/">BreizhCamp 2013</a>, à la fois en tant que visiteur mais aussi en tant qu'orateur.</p>
<span id="continue-reading"></span>
<p>J'y ai présenté la conférence "Papy fait du Scala", dont voici le support de présentation :</p>
<p><a rel="noopener" target="_blank" href="http://dlecan.github.io/breizhcamp2013/papy-fait-du-scala/"><img src="cover.png" alt="Support de présentation de la conférence" /></a></p>
<p>Et la vidéo :</p>
<div class="youtube is-flex is-justify-content-center is-align-items-center">
<iframe
width="848" height="510"
src="https://www.youtube.com/embed/ZXBfVUAfDuM"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>
Configurer Play Framework 2.x avec un repository Artifactory
2013-06-03T00:00:00+00:00
2013-06-03T00:00:00+00:00
https://dlecan.com/blog/configurer-play-framework-repository-artifactory/
<p><a rel="noopener" target="_blank" href="http://www.playframework.com/">Play Framework</a> utilise <a rel="noopener" target="_blank" href="http://www.scala-sbt.org/">Scala SBT</a> comme outil de build depuis la version 2.0.
<em>A la Maven</em>, il télécharge les dépendances de votre projet Play Framework depuis des dépôts centralisés, comme <a rel="noopener" target="_blank" href="http://repo1.maven.org/maven2/">Maven Central</a>.</p>
<span id="continue-reading"></span>
<p>Cette technique est très intéressante, mais il faut bien tenir compte des inconvénients induits :</p>
<ol>
<li>
<p>Pas de maîtrise des dépendances ou des dépôts configurés par les développeurs : on télécharge n'importe quoi depuis n'importe où</p>
</li>
<li>
<p>Gâchis de bande passante / latence : chaque développeur télécharge chaque dépendance depuis Internet, là où une mutualisation depuis un
serveur localisé dans le réseau de l'entreprise ferait économiser de la bande passante et gagner en réactivité (latence réduite)</p>
</li>
<li>
<p>Vous ne pouvez pas dépendre d'artifacts uniquement internes à votre entreprise (sans les publier sur Internet)</p>
</li>
</ol>
<p>En entreprise, 1/ est généralement résolu par "blocage naturel" : on ne peut pas télécharger depuis Internet. 2/ et 3/ peuvent se résoudre à l'aide d'un serveur proxy dédié à Maven, SBT, ... comme <a rel="noopener" target="_blank" href="http://www.sonatype.org/nexus/">Sonatype Nexus</a> ou <a rel="noopener" target="_blank" href="http://www.jfrog.com/home/v_artifactory_opensource_overview">JFrog Artifactory</a>.</p>
<p>Comment paramétrer Play Framework pour utiliser Artifactory ?</p>
<p><a href="https://dlecan.com/blog/configurer-scala-sbt-repository-artifactory/">J'ai déjà expliqué comment configurer SBT pour utiliser Artifactory</a>, mais, bien que Play Framework utilise SBT, ces explications ne s'y appliquent pas (pour le moment). SBT étant embarqué dans Play Framework, il ne lit pas les instructions de configuration fournies en ligne de commande.</p>
<p>Pas de différence du côté d'Artifactory en revanche.</p>
<p>Par la suite, je suppose que la variable <code>PLAY_HOME</code> pointe vers votre installation de Play Framework 2.x.</p>
<h2 id="configurer-sbt-pour-lire-les-depots-miroirs">Configurer SBT pour lire les dépôts "miroirs"</h2>
<p>Créez le fichier <code>~/sbt/.repositories</code> avec le contenu suivant :</p>
<pre data-lang="properties" style="background-color:#2b303b;color:#c0c5ce;" class="language-properties "><code class="language-properties" data-lang="properties"><span>[repositories]
</span><span> local
</span><span> maven-local
</span><span> ivy-proxy-releases: </span><span style="color:#a3be8c;">http://localhost:8180/artifactory/ivy-remote-repos/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
</span><span> maven-proxy-releases: </span><span style="color:#a3be8c;">http://localhost:8180/artifactory/maven-remote-repos/
</span></code></pre>
<p>Ce fichier indique à SBT l'ensemble des dépôts qu'il peut consulter pour résoudre les dépendances :</p>
<ul>
<li>
<p><code>local</code> : dépôt Ivy local par défaut, localisé dans <code>~/.ivy2/</code></p>
</li>
<li>
<p><code>maven-local</code> : dépôt Maven local par défaut, localisé dans <code>~/.m2/repository/</code></p>
</li>
<li>
<p><code>ivy-proxy-releases</code> : suivi d'une URL et d'un pattern, on indique à SBT qu'il pourra trouver les artifacts qui respectent ce pattern dans ce dépôts (pattern Ivy)</p>
</li>
<li>
<p><code>maven-proxy-releases</code> : suivi d'une URL, le dépôt au format Maven pour les autres dépendances</p>
</li>
</ul>
<h2 id="forcer-play-framework-a-lire-le-fichier-sbt-repositories">Forcer Play Framework à lire le fichier <code>~/sbt/.repositories</code></h2>
<p>Éditez le fichier <code>$PLAY_HOME/framework/sbt/sbt.boot.properties</code> et complétez le bloc suivant :</p>
<pre data-lang="properties" style="background-color:#2b303b;color:#c0c5ce;" class="language-properties "><code class="language-properties" data-lang="properties"><span>...
</span><span>[ivy]
</span><span> ivy-home: </span><span style="color:#a3be8c;">${play.home}/../repository
</span><span>
</span></code></pre>
<p>De cette manière :</p>
<pre data-lang="properties" style="background-color:#2b303b;color:#c0c5ce;" class="language-properties "><code class="language-properties" data-lang="properties"><span>...
</span><span>[ivy]
</span><span> ivy-home: </span><span style="color:#a3be8c;">${play.home}/../repository
</span><span> override-build-repos: </span><span style="color:#a3be8c;">${sbt.override.build.repos-true}
</span><span> repository-config: </span><span style="color:#a3be8c;">${sbt.global.base-${user.home}/.sbt}/repositories
</span><span>
</span></code></pre>
<p>Avec ces deux instructions, on force Play Framework à utiliser uniquement les dépôts configurés dans le fichier <code>~/sbt/.repositories</code>.</p>
<h2 id="tester">Tester</h2>
<p>Commencez par nettoyer votre dépôt local de cache de Play Framework (par précaution, je vous propose de simplement le déplacer) :</p>
<pre data-lang="sh" style="background-color:#2b303b;color:#c0c5ce;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#bf616a;">mv </span><span>$</span><span style="color:#bf616a;">PLAY_HOME</span><span>/repository/cache $</span><span style="color:#bf616a;">PLAY_HOME</span><span>/repository/cache.old
</span><span>
</span></code></pre>
<p>Postionnez-vous dans un projet Play, et testez :</p>
<pre data-lang="sh" style="background-color:#2b303b;color:#c0c5ce;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#bf616a;">dlecan@portable:~/dev/projet_test$</span><span> play
</span><span style="color:#bf616a;">[info]</span><span> Loading global plugins from /home/dlecan/.sbt/plugins
</span><span style="color:#bf616a;">[info]</span><span> Updating {file:/home/dlecan/.sbt/plugins/}default-ccfcd1...
</span><span style="color:#bf616a;">[info]</span><span> Resolving org.scala-sbt#precompiled-2_10_0;</span><span style="color:#bf616a;">0.12.2</span><span> ...
</span><span style="color:#bf616a;">[info]</span><span> downloading http://localhost:8180/artifactory/ivy-remote-repos/com.typesafe.sbt/sbt-pgp/scala_2.9.2/sbt_0.12/0.8/jars/sbt-pgp.jar ...
</span><span style="color:#bf616a;">[info] </span><span style="color:#b48ead;">[</span><span>SUCCESSFUL </span><span style="color:#b48ead;">]</span><span> com.typesafe.sbt#sbt-pgp;</span><span style="color:#bf616a;">0.8!sbt-pgp.jar</span><span> (50ms)
</span><span style="color:#bf616a;">[info]</span><span> downloading http://localhost:8180/artifactory/maven-remote-repos/com/github/mpeltonen/sbt-idea_2.9.2_0.12/1.4.0/sbt-idea-1.4.0.jar ...
</span><span style="color:#bf616a;">[info] </span><span style="color:#b48ead;">[</span><span>SUCCESSFUL </span><span style="color:#b48ead;">]</span><span> com.github.mpeltonen#sbt-idea;</span><span style="color:#bf616a;">1.4.0!sbt-idea.jar</span><span> (37ms)
</span><span style="color:#bf616a;">[info]</span><span> downloading http://localhost:8180/artifactory/maven-remote-repos/com/jsuereth/gpg-library_2.9.2/0.8/gpg-library_2.9.2-0.8.jar ...
</span><span style="color:#bf616a;">[info] </span><span style="color:#b48ead;">[</span><span>SUCCESSFUL </span><span style="color:#b48ead;">]</span><span> com.jsuereth#gpg-library_2.9.2;</span><span style="color:#bf616a;">0.8!gpg-library_2.9.2.jar</span><span> (29ms)
</span><span style="color:#bf616a;">[info]</span><span> downloading http://localhost:8180/artifactory/maven-remote-repos/org/bouncycastle/bcpg-jdk16/1.46/bcpg-jdk16-1.46.jar ...
</span><span style="color:#bf616a;">[info] </span><span style="color:#b48ead;">[</span><span>SUCCESSFUL </span><span style="color:#b48ead;">]</span><span> org.bouncycastle#bcpg-jdk16;</span><span style="color:#bf616a;">1.46!bcpg-jdk16.jar</span><span> (21ms)
</span><span style="color:#bf616a;">[info]</span><span> downloading http://localhost:8180/artifactory/maven-remote-repos/org/bouncycastle/bcprov-jdk16/1.46/bcprov-jdk16-1.46.jar ...
</span><span style="color:#bf616a;">[info] </span><span style="color:#b48ead;">[</span><span>SUCCESSFUL </span><span style="color:#b48ead;">]</span><span> org.bouncycastle#bcprov-jdk16;</span><span style="color:#bf616a;">1.46!bcprov-jdk16.jar</span><span> (41ms)
</span><span style="color:#bf616a;">[info]</span><span> Done updating.
</span><span style="color:#bf616a;">[info]</span><span> Loading project definition from /home/dlecan/dev/truc/project
</span><span style="color:#bf616a;">[info]</span><span> Set current project to truc (in build file:/home/dlecan/dev/truc/)
</span><span> </span><span style="color:#bf616a;">_</span><span> _
</span><span> </span><span style="color:#bf616a;">_</span><span> __ | | </span><span style="color:#bf616a;">__</span><span> _ _ _| |
</span><span>| '</span><span style="color:#a3be8c;">_ \| |/ _</span><span>' | || |</span><span style="color:#bf616a;">_</span><span>|
</span><span>| </span><span style="color:#bf616a;">__/</span><span>|</span><span style="color:#bf616a;">_</span><span>|</span><span style="color:#96b5b4;">\_</span><span style="color:#bf616a;">___</span><span>|</span><span style="color:#96b5b4;">\_</span><span style="color:#bf616a;">_</span><span> (_)
</span><span>|</span><span style="color:#bf616a;">_</span><span>| |</span><span style="color:#bf616a;">__/
</span><span>
</span><span style="color:#bf616a;">play!</span><span> 2.1.1 (using Java 1.7.0_21 and Scala 2.10.0)</span><span style="color:#bf616a;">,</span><span> http://www.playframework.org
</span><span>
</span><span>> Type "</span><span style="color:#a3be8c;">help play</span><span>" or "</span><span style="color:#a3be8c;">license</span><span>" for more information.
</span><span>> Type "</span><span style="color:#a3be8c;">exit</span><span>" or use Ctrl+D to leave this console.
</span><span>
</span><span style="color:#bf616a;">[projet_test]</span><span> $
</span><span>
</span></code></pre>
<p>Les dépendances sont téléchargées depuis <code>http://localhost:8180/...</code>, comme voulu.</p>
<p>Note : l'affichage obtenu peut varier selon vos dépendances paramétrées.</p>
Configurer Scala SBT avec un repository Artifactory
2013-04-24T00:00:00+00:00
2013-04-24T00:00:00+00:00
https://dlecan.com/blog/configurer-scala-sbt-repository-artifactory/
<p><a rel="noopener" target="_blank" title="Projet Scala SBT" href="http://www.scala-sbt.org/">Scala SBT</a> est à Scala ce que <a rel="noopener" target="_blank" title="Projet Maven" href="http://maven.apache.org/">Maven</a> est à Java : un outil de build dédié qui épouse la philosophie du langage.</p>
<p>Comme <a rel="noopener" target="_blank" title="Projet Gradle" href="http://www.gradle.org/">Gradle</a> avec Groovy, SBT est beaucoup plus puissant que Maven, dans le sens où, par exemple, étendre le build est beaucoup plus simple que de construire systématiquement un plugin (qu'il faut versionner, déployer, ...).</p>
<p>Cela dit, il ne faut pas occulter certains de ses inconvénients : incompatibilité des binaires de plugins entre versions de SBT, syntaxe complexe (en tout cas plus compliqué que du simple XML) ...</p>
<p>Scala SBT se répand petit à petit, avec <a rel="noopener" target="_blank" href="http://www.playframework.com/">Play Framework 2</a> comme cheval de Troie. En effet, Play2 a fait le choix de Scala SBT comme système de build :</p>
<ul>
<li>suite aux nombreuses critiques du système de build très fermé de Play 1</li>
<li>car Play2 est écrit en Scala et se marrie donc naturellement avec SBT</li>
</ul>
<p>Comme Maven, SBT se base sur le dépôt d'artifacts [Maven 2 Central]repo-maven2-central], mais aussi sur deux dépôts au format Ivy : <a rel="noopener" target="_blank" href="http://repo.typesafe.com/typesafe/ivy-releases/">celui de Typesafe</a> et celui <a rel="noopener" target="_blank" href="http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/">dédié à SBT</a>.</p>
<h1 id="scala-sbt-a-la-maven">Scala SBT <em>à la Maven</em></h1>
<p>Qui dit entreprise, dit "proxy", "firewall", "anti-virus", ... bref tout ce qui empêche des outils de build comme SBT ou Maven de fonctionner en standard. Vous avez alors deux possibilités :</p>
<ul>
<li>soit paramétrer le proxy permettant à l'outil d'accéder à Internet</li>
<li>soit paramétrer des dépôts d'artifacts <em>internes</em> à l'entreprise (ce qui ne nécessite plus d'accéder à Internet)</li>
</ul>
<p>C'est ce dernier paramétrage que je vous propose de décrire en détails.</p>
<h1 id="artifactory-comme-gestionnaire-d-artifacts-maven-et-ivy">Artifactory comme gestionnaire d'artifacts Maven et Ivy</h1>
<p>Voici ce que nous allons configurer :</p>
<p><img src="sbt-proxy-cloud-setup.png" alt="'Artifactory dans son environnement'" /></p>
<p>Il existe plusieurs outils qui peuvent permettre de gérer des artifacts, dans différents formats (Maven, RPM, Deb, P2, ...), comme <a rel="noopener" target="_blank" href="http://www.sonatype.org/nexus/">Sonatype Nexus</a> ou <a rel="noopener" target="_blank" href="http://www.jfrog.com/home/v_artifactory_opensource_overview">JFrog Artifactory</a>.</p>
<p>Ce qui compte pour SBT, c'est un gestionnaire d'artifacts qui supporte les formats Ivy et Maven. J'ai donc choisi Artifactory.</p>
<p>Je vous passe les détails d'installation de l'outil, ils sont <a rel="noopener" target="_blank" href="http://wiki.jfrog.org/confluence/display/RTF/Installing+Artifactory">très bien décrits dans sa documentation</a>.</p>
<p>La configuration des dépôts d'Artifactory s'effectue de la manière suivante :</p>
<ol>
<li>
<p>Ajouter les deux dépôts distants manquants, à savoir :</p>
<ul>
<li>
<p><code>sbt-plugin-releases</code> => <code>http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/</code></p>
</li>
<li>
<p><code>typesafe-ivy-releases</code> => <code>http://repo.typesafe.com/typesafe/ivy-releases/</code></p>
</li>
</ul>
</li>
<li>
<p>Ajouter un nouveau dépôt virtuel de type "Ivy" qui pointe sur <code>sbt-plugin-releases</code> et <code>typesafe-ivy-releases</code>. Je l'ai nommé <code>ivy-remote-repos</code>.</p>
<p><strong>Fusionner les dépôts Maven et Ivy en un seul est l'erreur à ne pas commettre</strong> (au format Maven par exemple). En effet, le format Ivy est plus riche que celui de Maven et des informations essentielles pour la résolution des plugins SBT seraient perdues.</p>
</li>
<li>
<p>(Optionnel) Si vous développez pour Play Framework, rajouter le dépôt Maven des releases Typesafe <code>http://repo.typesafe.com/typesafe/maven-releases/</code> à votre dépôt virtuel Maven peut être une bonne idée.</p>
</li>
</ol>
<p>A ce stade de la configuration d'Artifactory, ces trois paramètres sont disponibles :</p>
<ul>
<li>L'URL d'accès à votre instance d'Artifactory : <code>http://localhost:8180/artifactory/</code> par exemple</li>
<li>Le nom du dépôt Maven 2 virtuel qui agrège vos dépôts Maven 2 : <code>maven-remote-repos</code></li>
<li>Le nom du dépôt Ivy virtuel qui agrège vos dépôts Ivy : <code>ivy-remote-repos</code></li>
</ul>
<h1 id="configurer-scala-sbt">Configurer Scala SBT</h1>
<p>La configuration de SBT s'effectue en deux temps.</p>
<h2 id="ajouter-les-nouveaux-depots-a-la-configuration-generale-de-sbt">Ajouter les nouveaux dépôts à la configuration générale de SBT</h2>
<p>Pour cela, créez le fichier <code>~/sbt/.repositories</code> avec le contenu suivant :</p>
<pre data-lang="properties" style="background-color:#2b303b;color:#c0c5ce;" class="language-properties "><code class="language-properties" data-lang="properties"><span>[repositories]
</span><span> local
</span><span> maven-local
</span><span> ivy-proxy-releases: </span><span style="color:#a3be8c;">http://localhost:8180/artifactory/ivy-remote-repos/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
</span><span> maven-proxy-releases: </span><span style="color:#a3be8c;">http://localhost:8180/artifactory/maven-remote-repos/
</span></code></pre>
<p>Ce fichier indique à SBT l'ensemble des dépôts qu'il peut consulter pour résoudre les dépendances :</p>
<ul>
<li>
<p><code>local</code> : dépôt Ivy local par défaut, localisé dans <code>~/.ivy2/</code></p>
</li>
<li>
<p><code>maven-local</code> : dépôt Maven local par défaut, localisé dans <code>~/.m2/repository/</code></p>
</li>
<li>
<p><code>ivy-proxy-releases</code> : suivi d'une URL et d'un pattern, on indique à SBT qu'il pourra trouver les artifacts qui respectent ce pattern dans ce dépôts (pattern Ivy)</p>
</li>
<li>
<p><code>maven-proxy-releases</code> : suivi d'une URL, le dépôt au format Maven pour les autres dépendances</p>
</li>
</ul>
<h2 id="bloquer-tous-les-depots-configures-dans-les-builds-projets">Bloquer tous les dépôts configurés dans les builds projets</h2>
<p>La configuration précédente permet d'ajouter des dépôts à la configuration de SBT. Mais des dépôts peuvent être paramétrés dans chaque projet SBT, ce qui ne fonctionnera pas si vous n'avez pas accès à Internet. Si vous désirez que toutes les demandes de dépendances SBT passent par votre proxy Artifactory, il vous faut le paramétrage complémentaire suivant :</p>
<pre data-lang="sh" style="background-color:#2b303b;color:#c0c5ce;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#bf616a;">-Dsbt.override.build.repos</span><span>=</span><span style="color:#a3be8c;">true
</span></code></pre>
<p>A passer directement en argument à la ligne de commande Java qui lance SBT ou bien à rajouter à la variable <code>SBT_OPTS</code> par exemple.</p>
<h1 id="tester">Tester</h1>
<p>Un simple <code>sbt update</code> dans un projet SBT suffit à vérifier la bonne mise à jour des dépendances de SBT au travers d'Artifactory. Pour un projet Play2, la commande <code>play update</code> aura le même effet.</p>
<h1 id="et-pour-play-framework-2">Et pour Play Framework 2 ?</h1>
<p>Cette configuration ne fonctionnant pas pour Play Framework 2, <a href="https://dlecan.com/blog/configurer-play-framework-repository-artifactory/">consultez cet article dédié</a>.</p>
Bilan de 2 années de velotaf
2013-03-07T00:00:00+00:00
2013-03-07T00:00:00+00:00
https://dlecan.com/blog/bilan-2-annees-velotaf/
<p>Cela fait maintenant un peu plus de deux années que je "vélotafe" dans les rues de Nantes.</p>
<span id="continue-reading"></span><h2 id="pourquoi">Pourquoi ?</h2>
<p>Tout a commencé à l'été 2010, lorsque j'effectuais un parcours de 8,5 km en voiture dans
l'agglomération nantaise.
Période assez dramatique je dois reconnaître, puisque mes temps de parcours oscillaient
entre 45 minutes et 2h les mauvais vendredi soir de pluie.</p>
<p>Trajet rapidement insupportable, l'idée de parcourir ces kilomètres à vélo s'impose à moi,
avec deux exigences :</p>
<ul>
<li>obligation d'arriver sec le matin (costume de temps en temps) </li>
<li>30 min de trajet maximum, donc 17km/h de moyenne</li>
</ul>
<p>J'achète donc un vélo à assistance électrique à 2000€ en septembre 2010 avec
<a rel="noopener" target="_blank" href="http://www.nantesmetropole.fr/pratique/transports/subvention-pour-l-achat-d-un-velo-a-assistance-electrique-transport-et-deplacements-31822.kjsp">l'aide de 200€ de Nantes Métropole</a>
avec lequel je viens de franchir les 5000km il y a quelques semaines.</p>
<p>Depuis :</p>
<ul>
<li>
<p>nous n'avons toujours qu'une (petite) voiture familiale dans notre foyer : économies importantes d'achat, d'entretien et d'assurance d'un deuxième véhicule</p>
</li>
<li>
<p>j'ai perdu du poids : même sans vraiment forcer (arriver sec), c'est une séance de sport quotidienne</p>
</li>
<li>
<p>j'emmène mes enfants à l'école le matin en remorque, que je laisse à l'école. Ma femme la récupère en les ramenant le soir</p>
</li>
<li>
<p>ma société a déménagé et franchi le périphérique ce qui fait 20km quotidiens désormais. J'atteins la limite du vélo, mais je suis encore "gagnant" face à la voiture</p>
</li>
</ul>
<h2 id="reactions-des-autres">Réactions des autres</h2>
<p>Fréquemment la même séquence de réactions : d'abord admiratifs :</p>
<blockquote>
<p>Whoa ! 16km par jour de vélo ? Impressionnant !</p>
</blockquote>
<p>Puis, quand j'annonce que j'ai un vélo à assistance électrique et que sans
lui ce n'est pas faisable (arriver sec au boulot, vitesse moyenne élevée, ...), ils sont
sarcastiques :</p>
<blockquote>
<p>Ah ?! Un vélo électrique... comme un scooter, quoi. Trop facile...</p>
</blockquote>
<p>Comme si je trichais. Je cherche toujours à quel jeu ils pensent que je triche.</p>
<p>Quelques-uns se sont décidés à prendre leur vélo pour venir au travail et sont très contents de leur choix.</p>
<p>D'autres en parlent et ne dépasseront sans doute pas ce stade.
D'autres encore disent qu'ils n'ont pas besoin du vélo "parce qu'il n'y a pas de bouchons sur leur trajet".</p>
<h2 id="les-freins-au-velotaf">Les freins au vélotaf</h2>
<p>Le premier frein au vélotaf, c'est la difficulté à se séparer de sa voiture. Il y a une véritable addiction
à la voiture dans notre société et un grand sentiment de liberté avec : faire ses courses, emmener/ramener
ces enfants de l'école, gérer les imprévus, ...
Ce sont des préjugés, mais on ne pense pas avoir une liberté similaire en vélo. Seulement "similaire"
car on ne peut pas toujours tout faire en vélo non plus, c'est une question d'organisation.</p>
<p>J'ai réussi à m'en affranchir probablement parce que j'ai une piètre image de la voiture : ruineuse,
ennuyante, pénible à garer, ...
Attention, je n'en nie pas les avantages (je fais mes courses avec une fois par semaine, je vais à la
plage, ...), mais au quotidien, je trouve que les inconvénients prennent le dessus. Je prends tout
même la voiture 2-3j par mois pour aller à mon travail (météo trop difficile, client trop éloigné, ...).</p>
<p>Après viennent effectivement les inconvénients du vélo (pluie, vent fort de face, froid, ...) mais
ceux qui sont réellement motivés sont peu rebutés, sauf en cas de dangers (verglas par exemple).</p>
<h2 id="pourquoi-s-y-mettre">Pourquoi s'y mettre ?</h2>
<ul>
<li>
<p>Comptez combien votre deuxième voiture familiale coûte et ce que vous pourriez économiser (si en
plus c'est un diesel, ça ne va pas s'arranger :-)</p>
</li>
<li>
<p>Comptez le temps perdu en voiture et le temps gagné à vélo (séance de sport incluse)</p>
</li>
<li>
<p>Pensez aux bénéfices sur votre santé</p>
</li>
</ul>
Configure SBT credentials on Cloudbees platform to publish artifacts
2013-01-21T00:00:00+00:00
2013-01-21T00:00:00+00:00
https://dlecan.com/blog/configure-sbt-credentials-on-cloudbees-to-publish-artifacts/
<p>When you want to deploy your Scala artifacts (or anything else) with <a rel="noopener" target="_blank" href="http://www.scala-sbt.org">SBT</a>, its reference documentation <a rel="noopener" target="_blank" href="http://www.scala-sbt.org/release/docs/Community/Using-Sonatype.html#fourth-adding-credentials">explains well how to configure</a> your own repository's credentials.</p>
<p>Great, just create a bunch of <code>*.sbt</code> file in <code>~/.sbt</code> folder. Easy, simple.</p>
<p>But wait, I'm trying to publish artifacts from a Cloudbees Jenkins instance. How can I copy my <code>*.sbt</code> files into `~/.sbt``on Cloudbees Jenkins platform? You can't.</p>
<p>On Cloudbees, all files handled by Jenkins come from either your SCM (GIT, SVN, ...) or from your private repository: <code>/private/<my_account>/</code> (<a rel="noopener" target="_blank" href="http://wiki.cloudbees.com/bin/view/DEV/Sharing+Files+with+Build+Executors">you can upload files in thanks to WebDAV</a>).</p>
<p>As I want to load credentials in SBT, that is to say secret passwords, I want to the 2nd source.</p>
<p><em>Note</em>: yes, I could have setup the following configuration in my build:</p>
<pre data-lang="scala" style="background-color:#2b303b;color:#c0c5ce;" class="language-scala "><code class="language-scala" data-lang="scala"><span>credentials += Credentials(file("</span><span style="color:#a3be8c;">/private/<my_account>/.credentials</span><span>"))
</span></code></pre>
<p>But, you should avoid it for the next reasons:</p>
<ul>
<li>your build is now platform-dependent</li>
<li>as this is a project's configuration, you have to duplicate it in all of your project</li>
</ul>
<p>So it's much better to use <code>*.sbt</code> files to configure global credentials, but how to do it on Cloudbees ?</p>
<h2 id="create-and-upload-your-sbt-file-your-private-folder">Create and upload your <code>*.sbt</code> file your private folder</h2>
<p>I have chosen <a rel="noopener" target="_blank" href="http://wiki.cloudbees.com/bin/view/DEV/Sharing+Files+with+Build+Executors">to copy all my <code>*.sbt</code> files</a> into <code>/private/<my_account>/.sbt</code> folder.</p>
<h2 id="create-a-new-shell-script">Create a new shell script</h2>
<p>Create this new shell script <code>/private/<my_account>/bin/sbt-setup.sh</code> with the following content:</p>
<pre data-lang="sh" style="background-color:#2b303b;color:#c0c5ce;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#65737e;">#!/bin/sh
</span><span>
</span><span style="color:#bf616a;">mkdir -p ~</span><span>/.sbt
</span><span style="color:#b48ead;">for</span><span> f </span><span style="color:#b48ead;">in</span><span> /private/<my_account>/.sbt/*.sbt
</span><span style="color:#b48ead;">do
</span><span> </span><span style="color:#bf616a;">ln -s </span><span>$</span><span style="color:#bf616a;">f ~</span><span>/.sbt/
</span><span style="color:#b48ead;">done
</span><span>```
</span><span style="color:#bf616a;">This</span><span> script will create a symbolic link in `</span><span style="color:#bf616a;">~</span><span>/.sbt/` </span><span style="color:#b48ead;">for</span><span> each files found </span><span style="color:#b48ead;">in </span><span>`</span><span style="color:#bf616a;">/private/</span><span><my_account>/.sbt`.
</span><span style="color:#bf616a;">This</span><span> will work regardless of the Jenkins slave selected by the master.
</span><span>
</span><span style="color:#65737e;">## Add a new Jenkins Job to excute the shell script
</span><span>
</span><span style="color:#bf616a;">Before</span><span> a SBT build which requires credentials (eg. for `publish` </span><span style="color:#bf616a;">task</span><span>)</span><span style="color:#bf616a;">,</span><span> create a new Jenkins job :
</span><span>
</span><span>```sh
</span><span style="color:#bf616a;">/bin/sh</span><span> /private/<my_account>/bin/sbt-setup.sh
</span><span>
</span></code></pre>
<p>Save and run your job.</p>
<p>Voilà, that's all folks!</p>
Les outils météo du vélotafeur
2012-11-30T00:00:00+00:00
2012-11-30T00:00:00+00:00
https://dlecan.com/blog/outils-meteo-velotafeur/
<p>Je suis un ardent partisan du vélo pour aller travailler et je ne rate jamais une occasion d'en faire la promotion.
Évidemment, tout le monde me rétorque : "oui, mais moi je ne peux parce que ..." (au choix) :</p>
<ul>
<li>J'ai mes enfants à poser/prendre à la crèche/école/collège, ...</li>
<li>Je fais mes courses en allant/rentrant du travail</li>
<li>J'ai trop de distance à parcourir et je veux arriver sec au travail (les vélos à assistance électrique sont faits pour cela)</li>
<li>...</li>
<li>Il pleut trop souvent : ah !?</li>
</ul>
<p>Ah, la pluie, l'ennemi juré du cycliste, après le casque au-dessus de la mise en plis ou des brushings ?
Pleut-il si souvent ? Pleut-il vraiment au moment où vous prenez votre vélo pour aller travailler ?</p>
<p>Après presque 5000 km parcouru à Nantes en deux ans, je peux vous affirmer qu'il pleut en fait rarement au moment où l'on a besoin de son vélo (scoop !). Donc aucune excuse pour ne pas prendre son vélo ! ;-)</p>
<p>Mais il arrive tout de même qu'il pleuve et nous allons voir que cette situation peut être gérée par différents outils.</p>
<h2 id="previsions-meteo">Prévisions météo</h2>
<p><a rel="noopener" target="_blank" href="http://www.meteo.fr/">Météo France</a>, <a rel="noopener" target="_blank" href="http://www.lachainemeteo.com/">La Chaine Météo</a>, ... sont des sites généralistes permettant de connaître les tendances météo par demi-journée : il devrait pleuvoir ce matin, il devrait faire beau cet après-midi.</p>
<p>On est dans le conditionnel : s'il prévoir de la pluie ce matin, quand exactement ? A 9h ? Gênant pour aller au travail à vélo. A 11h ? Aucun problème, vous pouvez prendre votre vélo pour aller travailler.</p>
<p>Ces prévisions sont intéressantes, mais pas assez précises pour déterminer si vous pouvez prendre votre vélo ou non.</p>
<p>J'ai un faible pour les sites Météo-ville (comme <a rel="noopener" target="_blank" href="http://www.meteo-nantes.net/">Météo-Nantes</a>), dont les prévisions sont très régulièrement mises à jour et très justes à court terme (1-2j). Après, c'est comme jouer à la roulette de toutes façons ;-)</p>
<h2 id="pluie-a-1-heure">Pluie à 1 heure</h2>
<p>La prévision peut être améliorée avec le système "Pluie à 1 heure" de <a rel="noopener" target="_blank" href="http://france.meteofrance.com/france/meteo?PREVISIONS_PORTLET.path=previsionspluie/">Météo France</a>.
Avec ce système, vous pouvez savoir s'il va pleuvoir sur une ville dans l'heure qui vient. Intéressant.</p>
<p>Mais dans la pratique, il n'est pas très fiable et surtout, la zone couverte est beaucoup trop importante : il peut pleuvoir sur une ville au nord, mais vous circulez au sud de celle-ci. Il va donc vous dissuader de prendre votre vélo, alors qu'il ne pleuvra pas sur votre trajet.</p>
<p>Vous noterez au passage l'adresse impossible à retenir du service : http://france.meteofrance.com/france/meteo?PREVISIONS_PORTLET.path=previsionspluie. http://pluie.meteo.fr/ aurait tout de même été plus simple.</p>
<h2 id="cartes-radar-des-pluies">Cartes radar des pluies</h2>
<p>Les cartes radar des pluies sont l'outil ultime de prévision (prédiction ?) des pluies à très court terme, comme sur <a rel="noopener" target="_blank" href="http://www.meteox.com">Meteox</a>.</p>
<p>Vous voyez concrètement où sont les pluies, avec quelle intensité et dans quelle direction elles vont grâce à une animation temporelle sur les 2 dernière heures.</p>
<p>Ces cartes sont aussi disponibles sur mobile, ce qui les rend incontournables :</p>
<ul>
<li>Android : <a rel="noopener" target="_blank" href="https://play.google.com/store/apps/details?id=com.neenbedankt.rainydays">Rainy Days</a> ou les <a rel="noopener" target="_blank" href="http://www.meteo-nantes.net/mobile/">applis Météo-ville</a></li>
<li>iPhone : les <a rel="noopener" target="_blank" href="http://www.meteo-nantes.net/mobile/">applis Météo-ville</a></li>
</ul>
<p>Attention, l'interprétation de ces cartes nécessite un peu d'expérience. Les pluies très fines n'y sont pas visibles par exemple, ou bien on peut sous-estimer la vitesse de progression d'une zone de pluie et se retrouver trempé (ou l'inverse :-).</p>
<p>Mon meilleur outil de vélotafeur au quotidien.</p>
<h2 id="et-quand-tout-cela-ne-suffit-pas">Et quand tout cela ne suffit pas ...</h2>
<p>Dites-vous bien que la pluie est réellement gênante uniquement lorsque vous allez à votre travail (arriver sec, ne pas sentir le chien mouillé, ...), pas quand vous en revenez. Vous pouvez vous changer en rentrant chez vous ou avoir une famille tolérante avec les odeurs corporelles ;-) Donc les annonces de pluie pour la fin de journée ne doivent pas vous décourager de prendre votre vélo !</p>
Un blog, un arbre
2012-09-12T00:00:00+00:00
2012-09-12T00:00:00+00:00
https://dlecan.com/blog/un-blog-un-arbre/
<p>J'ai décidé de soutenir l'action "Blog zéro Carbone" de <a rel="noopener" target="_blank" href="http://www.bonial.fr/">Petits gestes écolos</a> qui vise
à <a rel="noopener" target="_blank" href="http://www.bonial.fr/environnement/blog-neutre-en-carbone/un-blog-un-arbre-principe/">planter un arbre pour chaque blog</a>
déclaré auprès d'eux.</p>
<p>Le principe est simple :</p>
<ul>
<li>Je publie un petit article sur la démarche et j'appose un badge sur mon blog (ci-contre)</li>
<li>Je les préviens via blog-zerocarbone@bonial.fr</li>
<li>Ils se chargent de tout pour la plantation de mon arbre en Bretagne</li>
</ul>
<p>Reste plus qu'à trouver, par la suite, un moyen d'identifier mon arbre dans la plantation et lui rendre visite régulièrement 😄</p>
Partage de connexion Internet avec Android par câble USB
2012-08-16T00:00:00+00:00
2012-08-16T00:00:00+00:00
https://dlecan.com/blog/partage-de-connection-internet-avec-android-par-cable-usb/
<p>Depuis Free Mobile, il est possible de partager la connexion Internet de son mobile avec son ordinateur, sa tablette, ... sans coût supplémentaire.
Si vous devez payer, changez d'opérateur.</p>
<p>Encore faut-il savoir comment faire (câble USB, Wifi, Bluetooth), que ce soit sur le smartphone ou l'ordinateur.</p>
<p>On trouve moultes applications de partage de connexion (tether/tethering) plus ou moins bridées et payantes alors que Google <a rel="noopener" target="_blank" href="http://www.android.com/tether">fournit désormais tout cela gratuitement</a>, même <a rel="noopener" target="_blank" href="http://www.android.com/drivers/tetherxp.inf">les pilotes pour Windows XP</a> (nécessaires pour partager la connexion au travers d'un câble USB).</p>
<p>Simple et gratuit.</p>
Play2War 0.7 is out!
2012-07-26T00:00:00+00:00
2012-07-26T00:00:00+00:00
https://dlecan.com/blog/play2war-0-7-is-out/
<h2 id="a-major-release">A major release</h2>
<p>Despite of his version number, [Play2War](https://github.com/dlecan/play2-war-plugin( v0.7 is
really a major release of this plugin for <a rel="noopener" target="_blank" href="http://www.playframework.org/">Play Framework 2</a>,
the famous productive web framework:</p>
<blockquote>
<p>Servlet 2.5 containers can now be used to deploy your Play applications!</p>
</blockquote>
<p>Servlet 2.5 containers means Tomcat 6, Jetty 7, ...</p>
<p>But this compatibility as a price: performances. They are worth than with Servlet 3.0,
themselves worth than with native Play 2.</p>
<p>Two threads are indeed necessary to compute each request:</p>
<ul>
<li>one for handling HTTP request</li>
<li>one for Akka asynchronous computing</li>
</ul>
<p>Standard Java synchronization mechanisms (wait/notify) are then used to make theses threads work together.
Of course, they are managed by threads pools, but synchronization has a cost. So if you need high performances
and have to deploy WAR packages, please upgrade to a modern Servlet 3.0 container, such as Tomcat 7,
Jetty 8, JBoss 7.x, Glassfish 3.x (not tested yet), ...</p>
<p>Don't forget to look at full <a rel="noopener" target="_blank" href="https://github.com/dlecan/play2-war-plugin/wiki/Changelog">Changelog</a>.</p>
<h2 id="upgrade-your-project-s-configuration">Upgrade your project's configuration</h2>
<p>Switching between Servlet 2.5 and 3.0 requires configuration, so you will need to upgrade to Play project
to be compatible with Play2War 0.7.</p>
<p>Here is a typical Play2 project <code>project/Build.scala</code> using Play2war v0.6:</p>
<pre data-lang="scala" style="background-color:#2b303b;color:#c0c5ce;" class="language-scala "><code class="language-scala" data-lang="scala"><span style="color:#b48ead;">import</span><span> sbt.</span><span style="color:#bf616a;">_
</span><span style="color:#b48ead;">import</span><span> Keys.</span><span style="color:#bf616a;">_
</span><span style="color:#b48ead;">import</span><span> PlayProject.</span><span style="color:#bf616a;">_
</span><span>
</span><span style="color:#b48ead;">object</span><span style="color:#ebcb8b;"> ApplicationBuild </span><span style="color:#b48ead;">extends </span><span style="color:#a3be8c;">Build </span><span style="color:#eff1f5;">{
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appName </span><span>= "</span><span style="color:#a3be8c;">myproject</span><span>"
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appVersion </span><span>= "</span><span style="color:#a3be8c;">1.0-SNAPSHOT</span><span>"
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appDependencies </span><span>= </span><span style="color:#eff1f5;">Seq(
</span><span style="color:#eff1f5;"> </span><span>"</span><span style="color:#a3be8c;">com.github.play2war</span><span>"</span><span style="color:#eff1f5;"> %% </span><span>"</span><span style="color:#a3be8c;">play2-war-core</span><span>"</span><span style="color:#eff1f5;"> % </span><span>"</span><span style="color:#a3be8c;">0.6</span><span>"
</span><span style="color:#eff1f5;"> )
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">main </span><span>= </span><span style="color:#eff1f5;">PlayProject(appName, appVersion, appDependencies, mainLang </span><span>= </span><span style="color:#eff1f5;">JAVA).settings(
</span><span style="color:#eff1f5;"> resolvers += </span><span>"</span><span style="color:#a3be8c;">Play2war plugins release</span><span>"</span><span style="color:#eff1f5;"> at </span><span>"</span><span style="color:#a3be8c;">http://repository-play-war.forge.cloudbees.com/release/</span><span>"
</span><span style="color:#eff1f5;"> )
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;">}
</span></code></pre>
<p>Follow the next steps to upgrade it to play2War v0.7.</p>
<h3 id="remove-play2war-core-dependency">Remove Play2War core dependency</h3>
<p>Dependency to Plat2War core is not necessary anymore. It will be automatically setup by the plugin.</p>
<p>Before:</p>
<pre data-lang="scala" style="background-color:#2b303b;color:#c0c5ce;" class="language-scala "><code class="language-scala" data-lang="scala"><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appDependencies </span><span>= Seq(
</span><span> "</span><span style="color:#a3be8c;">com.github.play2war</span><span>" %% "</span><span style="color:#a3be8c;">play2-war-core</span><span>" % "</span><span style="color:#a3be8c;">0.6</span><span>"
</span><span>)
</span><span>
</span><span>...
</span><span>
</span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">main </span><span>= PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
</span><span> resolvers += "</span><span style="color:#a3be8c;">Play2war plugins release</span><span>" at "</span><span style="color:#a3be8c;">http://repository-play-war.forge.cloudbees.com/release/</span><span>"
</span><span>)
</span></code></pre>
<p>So, remove it.</p>
<p>After:</p>
<pre data-lang="scala" style="background-color:#2b303b;color:#c0c5ce;" class="language-scala "><code class="language-scala" data-lang="scala"><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appDependencies </span><span>= Seq(
</span><span> </span><span style="color:#65737e;">// Nothing or your other dependencies
</span><span>)
</span><span>
</span><span>...
</span><span>
</span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">main </span><span>= PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
</span><span> </span><span style="color:#65737e;">// Nothing or your other settings
</span><span>)
</span><span>
</span></code></pre>
<h3 id="update-play2war-plugin-version">Update Play2War plugin version</h3>
<p>As usual, update <code>project/plugin.sbt</code>:</p>
<pre data-lang="scala" style="background-color:#2b303b;color:#c0c5ce;" class="language-scala "><code class="language-scala" data-lang="scala"><span>addSbtPlugin("</span><span style="color:#a3be8c;">com.github.play2war</span><span>" % "</span><span style="color:#a3be8c;">play2-war-plugin</span><span>" % "</span><span style="color:#a3be8c;">0.7</span><span>")
</span></code></pre>
<h3 id="import-play2war-sbt-settings">Import Play2War SBT settings</h3>
<pre data-lang="scala" style="background-color:#2b303b;color:#c0c5ce;" class="language-scala "><code class="language-scala" data-lang="scala"><span>...
</span><span style="color:#b48ead;">import</span><span> PlayProject.</span><span style="color:#bf616a;">_
</span><span style="color:#b48ead;">import</span><span> com.github.play2war.plugin.</span><span style="color:#bf616a;">_
</span></code></pre>
<h3 id="move-all-settings-in-a-variable-and-add-play2war-sbt-settings-to-your-project-s-settings">Move all settings in a variable and add Play2War SBT settings to your project's settings</h3>
<pre data-lang="scala" style="background-color:#2b303b;color:#c0c5ce;" class="language-scala "><code class="language-scala" data-lang="scala"><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appVersion </span><span>= "</span><span style="color:#a3be8c;">1.0-SNAPSHOT</span><span>"
</span><span>
</span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">projectSettings </span><span>= Play2WarPlugin.play2WarSettings ++ Seq(
</span><span> </span><span style="color:#65737e;">// Your settings
</span><span>)
</span><span>
</span><span>...
</span><span>
</span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">main </span><span>= PlayProject(
</span><span> appName, appVersion, appDependencies, mainLang = JAVA
</span><span>).settings(projectSettings: _*)
</span></code></pre>
<h3 id="configure-servlet-container-version">Configure servlet container version</h3>
<pre data-lang="scala" style="background-color:#2b303b;color:#c0c5ce;" class="language-scala "><code class="language-scala" data-lang="scala"><span style="color:#b48ead;">val </span><span style="color:#bf616a;">projectSettings </span><span>= Play2WarPlugin.play2WarSettings ++ Seq(
</span><span> Play2WarKeys.servletVersion := "</span><span style="color:#a3be8c;">3.0</span><span>"
</span><span> </span><span style="color:#65737e;">// Or Play2WarKeys.servletVersion := "2.5"
</span><span>)
</span><span>
</span></code></pre>
<h3 id="final-project-file">Final project file</h3>
<pre data-lang="scala" style="background-color:#2b303b;color:#c0c5ce;" class="language-scala "><code class="language-scala" data-lang="scala"><span style="color:#b48ead;">import</span><span> sbt.</span><span style="color:#bf616a;">_
</span><span style="color:#b48ead;">import</span><span> Keys.</span><span style="color:#bf616a;">_
</span><span style="color:#b48ead;">import</span><span> PlayProject.</span><span style="color:#bf616a;">_
</span><span style="color:#b48ead;">import</span><span> com.github.play2war.plugin.</span><span style="color:#bf616a;">_
</span><span>
</span><span style="color:#b48ead;">object</span><span style="color:#ebcb8b;"> ApplicationBuild </span><span style="color:#b48ead;">extends </span><span style="color:#a3be8c;">Build </span><span style="color:#eff1f5;">{
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appName </span><span>= "</span><span style="color:#a3be8c;">myproject</span><span>"
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appVersion </span><span>= "</span><span style="color:#a3be8c;">1.0-SNAPSHOT</span><span>"
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">projectSettings </span><span>= </span><span style="color:#eff1f5;">Play2WarPlugin.play2WarSettings ++ Seq(
</span><span style="color:#eff1f5;"> Play2WarKeys.servletVersion := </span><span>"</span><span style="color:#a3be8c;">3.0</span><span>"
</span><span style="color:#eff1f5;"> )
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appDependencies </span><span>= </span><span style="color:#eff1f5;">Seq(
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Nothing
</span><span style="color:#eff1f5;"> )
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">main </span><span>= </span><span style="color:#eff1f5;">PlayProject(
</span><span style="color:#eff1f5;"> appName, appVersion, appDependencies, mainLang </span><span>= </span><span style="color:#eff1f5;">JAVA
</span><span style="color:#eff1f5;"> ).settings(projectSettings: </span><span>_*</span><span style="color:#eff1f5;">)
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;">}
</span></code></pre>
<h3 id="package-your-application">Package your application</h3>
<p>Then, package your application as usual: <code>sbt package</code> (or <code>play package</code>).</p>
Octopress continous integration
2012-07-03T00:00:00+00:00
2012-07-03T00:00:00+00:00
https://dlecan.com/blog/octopress-continous-integration/
<p><strong>Update 2012-11-30</strong>: update script to adapt to last Cloudbees changes.</p>
<p><a rel="noopener" target="_blank" href="http://octopress.org">Octopress</a> is great for blogging:</p>
<ul>
<li><a rel="noopener" target="_blank" href="http://daringfireball.net/projects/markdown/syntax/">Clear and easy-to-read syntax</a> thanks to <a rel="noopener" target="_blank" href="http://daringfireball.net/projects/markdown/syntax/">Markdown</a></li>
<li>Offline editing (write your post offline, push it to Github, see it in 'production)</li>
</ul>
<p>This blog is powered by Octopress.</p>
<p>But Octopress relies on Ruby rake to generate and deploy your blog posts, so you need to install them on each computer from where you want to deploy your blog.
And installing theses tools are generally a pain: ruby/rvm, rake, bundler, encoding issues between platforms, ...</p>
<p>So the perfect "blog post flow" would be:</p>
<ol>
<li>write blog post everywhere: laptop, personal/professional computer, ...</li>
<li>generate and deploy from only one place</li>
</ol>
<p>I found a centralized place to generate and deploy this blog: a <a rel="noopener" target="_blank" href="http://www.cloudbees.com">Cloudbees</a> Jenkins instance!
Jenkins is a continuous integration server, which allows you to build and deploy Java, Ruby, ... applications.</p>
<p>What about a ruby/rake/bundler build ?</p>
<p>Configure a new free-style projet, with the following <em>shell</em> job:</p>
<pre data-lang="sh" style="background-color:#2b303b;color:#c0c5ce;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#65737e;">#export LC_ALL=fr_FR.UTF-8 # uncomment this if you need to force locale
</span><span style="color:#65737e;">#export LANG=fr_FR.UTF-8 # uncomment this if you need to force locale
</span><span style="color:#bf616a;">curl -s -o</span><span> use-ruby https://repository-cloudbees.forge.cloudbees.com/distributions/ci-addons/ruby/use-ruby
</span><span style="color:#bf616a;">RUBY_VERSION</span><span>=</span><span style="color:#a3be8c;">1.9.3-p327 </span><span>\
</span><span style="color:#96b5b4;">source</span><span> ./use-ruby
</span><span style="color:#bf616a;">ln -fs</span><span> /scratch/jenkins/ruby /scratch/jenkins/rubies
</span><span style="color:#bf616a;">gem</span><span> install</span><span style="color:#bf616a;"> --conservative</span><span> bundler
</span><span style="color:#bf616a;">bundle</span><span> install
</span><span style="color:#bf616a;">rake</span><span> setup_github_pages</span><span style="color:#b48ead;">[</span><span>git@github.com:dlecan/dlecan.github.com.git</span><span style="color:#b48ead;">]
</span><span style="color:#bf616a;">rake</span><span> generate
</span><span style="color:#bf616a;">rake</span><span> deploy
</span></code></pre>
<p>That's it! Just replace <code>git@github.com:dlecan/dlecan.github.com.git</code> by your Git repository and let Jenkins do the job for you!</p>
<p>This blog is also built thanks to Cloudbees :) {% img right http://web-static-cloudfront.s3.amazonaws.com/images/badges/BuiltOnDEV.png %}</p>
<p>See it in action on this <a rel="noopener" target="_blank" href="https://play-war.ci.cloudbees.com/job/dlecan.github.io/">Cloudbees Jenkins instance</a>.</p>
How to publish Play2 'dist' package ?
2012-06-21T00:00:00+00:00
2012-06-21T00:00:00+00:00
https://dlecan.com/blog/how-to-publish-play-framework-v2-dist-package/
<p>In an enterprise context, it is often necessary to deploy (maven) or publish (Ivy/SBT) artifacts in a central repository.</p>
<p>Here is a sample Play2 project configured to publish artifact in a local folder (<code>~/.ivy2/publish</code>), but you can easily adapt it to publish
to your central repository (<a rel="noopener" target="_blank" href="http://www.cakesolutions.net/teamblogs/2012/01/28/publishing-sbt-projects-to-nexus/">Nexus</a>, Artifactory, ...)</p>
<pre data-lang="scala" style="background-color:#2b303b;color:#c0c5ce;" class="language-scala "><code class="language-scala" data-lang="scala"><span style="color:#b48ead;">import</span><span> sbt.</span><span style="color:#bf616a;">_
</span><span style="color:#b48ead;">import</span><span> Keys.</span><span style="color:#bf616a;">_
</span><span style="color:#b48ead;">import</span><span> PlayProject.</span><span style="color:#bf616a;">_
</span><span>
</span><span style="color:#b48ead;">object</span><span style="color:#ebcb8b;"> ApplicationBuild </span><span style="color:#b48ead;">extends </span><span style="color:#a3be8c;">Build </span><span style="color:#eff1f5;">{
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appName </span><span>= "</span><span style="color:#a3be8c;">sample</span><span>"
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appVersion </span><span>= "</span><span style="color:#a3be8c;">1.0-SNAPSHOT</span><span>"
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Properties to add configure the new Artifact
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">lazy val </span><span style="color:#bf616a;">distSettings </span><span>= </span><span style="color:#eff1f5;">Seq[</span><span style="color:#ebcb8b;">Setting</span><span style="color:#eff1f5;">[</span><span style="color:#bf616a;">_</span><span style="color:#eff1f5;">]] (
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Type of the Artifact : zip
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Extension of the Artifact : zip
</span><span style="color:#eff1f5;"> artifact in dist <<= moduleName(</span><span style="color:#bf616a;">n </span><span style="color:#b48ead;">=> </span><span style="color:#eff1f5;">Artifact(n, </span><span>"</span><span style="color:#a3be8c;">zip</span><span>"</span><span style="color:#eff1f5;">, </span><span>"</span><span style="color:#a3be8c;">zip</span><span>"</span><span style="color:#eff1f5;">))
</span><span style="color:#eff1f5;"> ) ++ Seq(addArtifact(artifact in (Compile, dist), dist).settings: </span><span>_*</span><span style="color:#eff1f5;">)
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">appDependencies </span><span>= </span><span style="color:#eff1f5;">Seq(
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Add your project dependencies here,
</span><span style="color:#eff1f5;"> )
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#b48ead;">val </span><span style="color:#bf616a;">main </span><span>= </span><span style="color:#eff1f5;">PlayProject(appName, appVersion, appDependencies,
</span><span style="color:#eff1f5;"> mainLang </span><span>= </span><span style="color:#eff1f5;">SCALA,
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Don't forget to add defaultSettings !
</span><span style="color:#eff1f5;"> settings </span><span>= </span><span style="color:#eff1f5;">Defaults.defaultSettings ++ distSettings
</span><span style="color:#eff1f5;"> ).settings(
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Optional
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Disable jar for this project (useless)
</span><span style="color:#eff1f5;"> publishArtifact in (Compile, packageBin) := </span><span style="color:#d08770;">false</span><span style="color:#eff1f5;">,
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Disable scaladoc generation for this project (useless)
</span><span style="color:#eff1f5;"> publishArtifact in (Compile, packageDoc) := </span><span style="color:#d08770;">false</span><span style="color:#eff1f5;">,
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Disable source jar for this project (useless)
</span><span style="color:#eff1f5;"> publishArtifact in (Compile, packageSrc) := </span><span style="color:#d08770;">false</span><span style="color:#eff1f5;">,
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Where to 'publish'
</span><span style="color:#eff1f5;"> publishTo := Some(Resolver.file(</span><span>"</span><span style="color:#a3be8c;">file</span><span>"</span><span style="color:#eff1f5;">, file(Path.userHome.absolutePath + </span><span>"</span><span style="color:#a3be8c;">/.ivy2/publish</span><span>"</span><span style="color:#eff1f5;">))),
</span><span style="color:#eff1f5;">
</span><span style="color:#eff1f5;"> </span><span style="color:#65737e;">// Use Maven pattern to publish
</span><span style="color:#eff1f5;"> publishMavenStyle := </span><span style="color:#d08770;">true</span><span style="color:#eff1f5;">)
</span><span style="color:#eff1f5;">}
</span></code></pre>
<p>Next step: to be able to "release" a Play2 project with SBT (update version in project, tag, build and publish artifacts).</p>
FreeFileSync is looking for a Debian Mentor!
2011-11-30T00:00:00+00:00
2011-11-30T00:00:00+00:00
https://dlecan.com/blog/freefilesync-is-looking-for-a-debian-mentor/
<p><a href="http://mentors.debian.net/package/freefilesync">FreeFileSync is looking for a Debian Mentor</a> in order to be uploaded into Debian repository.</p><br />
<p>Can someone help me to find one ?</p><br />
<p><a href="http://mentors.debian.net/package/freefilesync">http://mentors.debian.net/package/freefilesync</a></p>
FreeFileSync 3.21 with Ubuntu Unity Integration
2011-08-16T00:00:00+00:00
2011-08-16T00:00:00+00:00
https://dlecan.com/blog/freefilesync-3-21-with-ubuntu-unity-integration/
<p>FreeFileSync 3.21 is available on its <a href="https://launchpad.net/%7Efreefilesync/+archive/ffs">official PPA</a>. For Ubuntu users, the main new feature is its integration with Unity.</p> <br />
<p>This version is the first one only available on Natty and later versions. Lucid (10.04) and Maverick (10.10) users, you are sticked to FreeFileSync v3.17.</p> <br />
<p>Install FreeFileSync [as usual](@/blog/2010-05-10-How-to-install-FreeFileSync-on-Ubuntu-PPA-Edited.md), or wait for an automatic software update !</p>
Installing OpenJDK 7 on Ubuntu Natty (PPA method) (Edited)
2011-08-08T00:00:00+00:00
2011-08-08T00:00:00+00:00
https://dlecan.com/blog/installing-openjdk-7-on-ubuntu-natty-ppa-method-edited/
<p><strong>Edit 2011-11-30 : this PPA is now deprecated as OpenJDK7 is available in Ubuntu Oneiric repositories.</strong></p><br />
<p>Many methods to install OpenJDK 7 on Ubuntu can be found on the Net :</p><br />
<ul><li>this <a href="https://launchpad.net/~openjdk/+archive/ppa">PPA</a>, but very old <br />
</li><li><a href="http://nikolavp.blogspot.com/2010/05/installing-jdk7-in-ubuntu.html">this method</a> by downloading OpenJDK from Oracle's website, but you need to do the same thing on each of your computers. </li></ul><br />
<p>OpenJDK 7 is "natively" available on Ubuntu Oneiric (11.10), but is not and won't be on Natty (11.04). But I need it now on Natty and I don't want to install it manually on each of my computers. More, I want a transparent migration when I will upgrade to Ubuntu Oneiric on next October.</p><br />
<p>So I decided to backport OpenJDK 7 Oneiric package to Natty and the result is available here : <a href="https://launchpad.net/~dlecan/+archive/openjdk">https://launchpad.net/~dlecan/+archive/openjdk<br /></a></p><br />
<p>Add this <strong>ppa:dlecan/openjdk</strong> to your Ubuntu and install openjdk-7-jre or openjdk-7-jdk.</p><br />
<script src="https://gist.github.com/1133900.js?file=gistfile1.sh"></script><br />
<br />
<p>I will support this ppa as long as I will upgrade to Ubuntu Oneiric.</p><br />
<p>Enjoy !</p>
Nouveau service pour les cyclistes sur Nantes
2011-06-27T00:00:00+00:00
2011-06-27T00:00:00+00:00
https://dlecan.com/blog/nouveau-service-pour-les-cyclistes-sur-nantes/
<p>Le service existait <a href="http://www.geovelo.fr/">de manière autonome</a> et a déjà été choisi <a href="http://vgps.paris.fr/">par la ville de Paris</a> en tant que service de calcul d'itinéraires à vélo, j'ai nommé Geovelo !<br /><br />
Nantes métropole <a href="http://www.nantesmetropole.fr/actualite/l-actualite-thematique/le-plan-velo-trace-la-route-transport-et-deplacements-38586.kjsp">vient aussi de choisir</a> <a href="http://geovelo.nantesmetropole.fr/">ce service</a> pour renseigner les cyclistes nantais, mais nous sommes gratifiés de <a href="http://www.geovelo.fr/blog/20/06/2011/geovelo-nantes-metropole/">bonus supplémentaires</a> exclusifs, notamment "[une] interface communautaire de notation de la cyclabilité".<br /><br />
Quid ? Il s'agit simplement de la possibilité d'évaluer les rues de Nantes de manière à affiner les calculs d'itinéraires ou bien à renseigner Nantes Métropole sur les améliorations qu'il faudrait apporter à la voirie.<br /><br />
J'ai décidé d'appliquer les règles suivantes aux notes que je donne sur le service :</p> <br />
<ul> <br />
<li>5 étoiles (4) : piste cyclable bien identifiée, séparée de la voie des voitures et des bus</li> <br />
<li>4 étoiles (3) : piste cyclable bien identifiée, séparée de la voie des voitures, mais partagée avec des bus par exemple<br /></li> <br />
<li>3 étoiles (2) : bande cyclable simple sur le bord de la voie des véhicules, matérialisée par une ligne blanche discontinue<br /></li> <br />
<li>2 étoiles (1) : pas de piste cyclable ou bien juste une flèche verte (inutile ?) sur le côté droit de la chaussée<br /></li> <br />
<li>1 étoile (0) : dangereux, chaussée dégradée : à éviter</li> <br />
</ul> <br />
<p>En ces temps d'ouverture des données, quelques questions me sont venues à l'esprit que j'ai rapidement posées <a href="http://www.geovelo.fr/blog/20/06/2011/geovelo-nantes-metropole/">sur le blog de Geovelo</a> :</p> <br />
<ul> <br />
<li>A quelle licence les données fournies par les internautes sont-elles soumise ?</li> <br />
<li>Est-il prévu une ouverture de ces données ?</li> <br />
</ul> <br />
<p>Les réponses fournies ne me surprennent pas : "... données ... propriétaires". Je ne blâme pas Geovelo, car c'est probablement Nantes Métropole qui impose son avis sur le sujet, mais je ne vois vraiment pas bien pourquoi de telle données ne pourraient pas être "ouvertes".<br /><br />
Je vais demander à <a href="http://libertic.wordpress.com/libertic/">l'association LiberTIC</a> ce qu'elle en pense, tiens ...</p>
FreeFileSync 3.11 pour Ubuntu 10.10 et 10.04
2010-11-03T00:00:00+00:00
2010-11-03T00:00:00+00:00
https://dlecan.com/blog/freefilesync-3-11-pour-ubuntu-10-10-et-10-04/
<p><a href="http://www.dlecan.com/archives/65-Des-nouvelles-de-FreeFileSync-3.9.html">Contrairement à ce que j'indiquais dans mon précédent billet</a>, FreeFileSync est finalement disponible pour Ubuntu 10.10 comme pour Ubuntu 10.04.</p> <br />
<p>En effet, j'ai réussi à <em>backporter</em> la librairie boost 1.44 disponible en <em>Debian experimental</em> pour Ubuntu 10.04 et 10.10. Combiné à une évolution du système de build introduite par ZenJu dans les sources de FreeFileSync et qui cassait le build du package, il m'a fallu plusieurs semaines pour réussir à contourner tous ces problèmes.</p> <br />
<p>Pendant ce temps, FFS 3.10 est sorti, puis FFS 3.11 et c'est cette version qui se trouve aujourd'hui dans le <a href="https://launchpad.net/~freefilesync/+archive/ffs">dépôt PPA du projet</a>.</p> <br />
<p>Voici les <em>changelogs</em> :</p> <br />
<ol> <br />
<li>FFS 3.10<br /> <br />
<ul> <br />
<li>Automatically solve daylight saving time and time zone shift issues on FAT/FAT32 (finally) </li> <br />
<li>Instantly resolve abandoned directory locks associated with local computer </li> <br />
<li>Show expanded directory name as tooltip and label text (resolves macros and relative paths) </li> <br />
<li>Do not copy relative file attributes for base target directories that are created implicitly </li> <br />
<li>Move dialogs by clicking (almost) anywhere </li> <br />
<li>RealtimeSync: ignore request for device removal on Samba shares </li> <br />
<li>Added UTF-8 BOM for CSV export </li> <br />
<li>Correctly handle window position on multi-screen desktop </li> <br />
<li>Disabled warning "database not yet existing" </li> <br />
<li>RealtimeSync: replaced delay by minimum idle time </li> <br />
<li>Maximum number of folder pairs configurable via GlobalSettings.xml (XML node <FolderPairsMax>) </li> <br />
<li>Added tooltips to display long filenames on main grid </li> <br />
<li>Keep application responsive when deleting large directories </li> <br />
<li>Vista/Windows 7: harmonize modification times shown on main grid with Windows Explorer <br /></li> <br />
<li>Changed background color to avoid unreadable texts in combination with certain color themes </li> <br />
<li>Toggle middle grid comparison result/sync preview with right mouse button click </li> <br />
<li>Further GUI enhancements/polishment/standard conformance </li> <br />
<li>Updated translation files<br /></li> <br />
</ul> <br />
</li> <br />
<li>FFS 3.11<br /> <br />
<ul> <br />
<li>Fixed migration issue: reasonable default value for number of folder pairs<br />
</li> <br />
<li>Better message box background color<br /></li> <br />
</ul> <br />
</li> <br />
</ol><br />
Des nouvelles de FreeFileSync 3.9
2010-09-03T00:00:00+00:00
2010-09-03T00:00:00+00:00
https://dlecan.com/blog/des-nouvelles-de-freefilesync-3-9/
<p>FreeFileSync 3.9 est sorti depuis quelques semaines déjà et j'ai pris du retard sur la construction du package pour Ubuntu.</p> <br />
<p>Zenju, son auteur, l'a beaucoup fait évoluer techniquement pour cette version, en ajoutant en particulier une dépendance vers une librairie d'utilitaires très intéressante d'un point de vue du développement : <a href="http://www.boost.org/">libboost</a>.</p> <br />
<p>Il y a cependant un problème : FFS 3.9 requiert la version 1.4<strong>2</strong> minimum de ce package quand Ubuntu 10.04 fourni la version 1.4<strong>0</strong> seulement.</p> <br />
<p> L'équation sera donc simple :</p> <br />
<ul> <br />
<li>FFS 3.8 : Ubuntu 10.04 et versions antérieures</li> <br />
<li>FFS 3.9 : Ubuntu 10.10 et versions supérieures</li> <br />
</ul>Rendez-vous donc courant octobre pour tester FFS 3.9 sur Ubuntu Maverick !<br />
Qui a la carte la plus juste de l'île de Nantes ?
2010-06-25T00:00:00+00:00
2010-06-25T00:00:00+00:00
https://dlecan.com/blog/qui-a-la-carte-la-plus-juste-de-lile-de-nantes/
<p>Il y 4 ans, il a fallu plusieurs années à TeleAtlas, le fournisseur de carte, pour prendre en <br />
compte la mise en sens unique de ma rue, avec pour conséquence des <br />
itinéraires sur ViaMichelin ou  Google Maps complètement erronés. Cette rue étant très longue, les indications proposées dans les itinéraires pouvaient conduire à des différences de 10-15 minutes selon la circulation !</p> <br />
<p>Très handicapant.</p> <br />
<p>J'habite aujourd'hui dans un quartier (République) dont le plan des rues a été largement modifié ces dernières années. Des rues ont été crées ou prolongées, ce qui a été diversement été pris en compte par les fournisseurs de carte TeleAtlas ou Navteq. Avec des répercussions sur les services calculant des itinéraires comme Google Maps, ViaMichelin ou Mappy.</p> <br />
<p>Voici les données que possèdent respectivement TeleAtlas et Navteq sur l'environnement de la place de la République à Nantes :</p> <br />
<p><!-- s9ymdb:12 --><img width="250" height="184" class="serendipity_image_center" style="border: 0px none; padding-left: 5px; padding-right: 5px;" src="http://www.dlecan.com/uploads/QuartierRepubliqueTeleAtlas.serendipityThumb.png" alt="" /> <!-- s9ymdb:10 --><img width="250" height="141" class="serendipity_image_center" style="border: 0px none; padding-left: 5px; padding-right: 5px;" src="http://www.dlecan.com/uploads/QuartierRepubliqueNAVTEQ.serendipityThumb.png" alt="" /></p> <br />
<p>Remarquez sur les images :</p> <br />
<ul> <br />
<li>En bas à gauche, il manque le boulevard de l'Estuaire sur la carte TeleAtlas</li> <br />
<li>Légèrement au dessus de la place de la république, la carte Navteq n'affiche pas une petite impasse</li> <br />
<li>En haut à droite, la carte TeleAtlas "oublie" une autre petite impasse</li> <br />
</ul> <br />
<p>Or, dans la réalité le boulevard de l'Estuaire existe bel est bien, il y a même des commerces et des médecins qui y travaillent ! Les pages jaunes connaissent le boulevard (lien direct impossible), mais ne peuvent pas afficher la plan correspondant via Mappy puisque le boulevard n'existe dans la base de données de TeleAtlas.</p> <br />
<p>Vous me direz que je chipote et qu'il suffit d'attendre qu'il soit pris en compte. Ce boulevard existe depuis 2008 et malgré une <a href="http://mapinsight.teleatlas.com/">suggestion de correction via l'outil de TeleAtlas</a> il y a un an, il n'existe pas.</p> <br />
<p>Navteq s'en tire mieux, mais ses fonds de carte sont très peu utilisés par les services de cartes ou d'itinéraires sur le web. Je ne connais que <a href="http://www.fr.map24.com/">Map24</a> qui soit partenaire.<br /></p> <br />
<p>Je récapitule :</p> <br />
<ul> <br />
<li>TeleAtlas a des cartes incomplètes, mais est le leader sur le web</li> <br />
<li>Navteq a une carte plus à jour, mais est très peu répandu sur le web</li> <br />
</ul> <br />
<p>La solution serait donc d'utiliser Map24 ?</p>
Nautilus du futur
2010-06-15T00:00:00+00:00
2010-06-15T00:00:00+00:00
https://dlecan.com/blog/nautilus-du-futur/
<p>Whaa, le Nautilus du futur ! Un Nautilus dont on peut configurer la barre d'outils, enlever les éléments redondants et afficher un chemin de navigation lisible ? Qui sépare proprement les répertoires utilisateur des disques de stockage ?<br /></p> <br />
<p>Le résultat :<br /><!-- s9ymdb:8 --><!-- s9ymdb:9 --><!-- s9ymdb:9 --><img width="250" height="198" src="http://www.dlecan.com/uploads/NautilusDuFutur.serendipityThumb.jpg" style="border: 0px none; padding-left: 5px; padding-right: 5px;" class="serendipity_image_center" alt="" /><br /></p> <br />
<p>Pas mal, comme résultat ! Je trouve cette organisation de Nautilus vraiment plus lisible, surtout quand on cache la barre de menu par défaut.<br /></p> <br />
<p>Vous vous dites que <a title="Bug Gnome 42834" href="https://bugzilla.gnome.org/show_bug.cgi?id=42834">ce bug</a>, ouvert sur le projet Nautilus de Gnome depuis septembre 2001 est résolu ? Malheureusement non <img src="http://www.dlecan.com/templates/default/img/emoticons/sad.png" alt=":-(" style="display: inline; vertical-align: bottom;" class="emoticon" /><br /></p> <br />
<p> </p> <br />
<p>Il s'agit d'un travail indépendant d'une personne qui en marre d'attendre des évolutions sur ce sujet. Une version de Nautilus modifiée est disponible sur le <a href="https://launchpad.net/nautilus-elementary">PPA nautilus-elementary</a>.</p> <br />
<p>Suivez les procédures décrites sur <a href="http://www.techdrivein.com/2010/05/what-is-nautilus-elementary-and-how-to.html">ce blog</a> (en) ou <a href="http://bl4g.free.fr/dotclear/index.php?post/2010/05/16/Nautilus-elementary-Breadcrumbs">celui-ci</a>, en français. N'hésitez pas à tenter la configuration du chemin de navigation ("breadcrumb"), le résultat est bien meilleur qu'avec celui par défaut.<br /></p> <br />
<p> </p> <br />
<p>Parmi les autres fonctionnalités :</p> <br />
<ul> <br />
<li> Système de zoom à l'aide d'une petite slidebar très pratique (en bas à droite de la capture)</li> <br />
<li>Possibilité de couper la fenêtre en deux pour afficher deux répertoires simultanément côte-à-côte (et les onglets sont gérés indépendamment dans chacune des zones !)<br /></li> <br />
</ul>
Nettoyer Ubuntu des programmes installés au travers d'un PPA
2010-06-01T00:00:00+00:00
2010-06-01T00:00:00+00:00
https://dlecan.com/blog/nettoyer-ubuntu-des-programmes-installes-au-travers-dun-ppa/
<p>Les <a href="http://doc.ubuntu-fr.org/ppa">PPA Ubuntu</a> sont bien pratiques pour tester ou évaluer des programmes qui ne sont pas encore dans les dépôts officiels d'Ubuntu ou bien dont on veut tester une version plus récente.</p> <br />
<p>Certains programmes fournissent cependant de nouvelles versions de librairies déjà présentes dans les dépôts Ubuntu et, lors de la désinstallation du paquet et la suppression du PPA, celles-ci restent dans la version fournie par le PPA et ne sont plus mises à jour par la suite !</p> <br />
<p><a href="http://www.webupd8.org/2009/12/remove-ppa-repositories-via-command.html">Ce script</a> (en bas de la page) permet de supprimer un PPA, de supprimer les paquets qu'il fournit et de les remplacer par ceux existants dans les dépôts officiels.<br /></p>
FreeFileSync 3.7
2010-05-20T00:00:00+00:00
2010-05-20T00:00:00+00:00
https://dlecan.com/blog/freefilesync-3-7/
<p><!-- s9ymdb:7 -->Les versions de FreeFileSync s'enchainent pour ZenJu (l'auteur du programme), au rythme d'une version tous les mois et demi environ.<br /></p> <br />
<p> <a title="Changelog complet" href="https://sourceforge.net/projects/freefilesync/files/freefilesync/v3.7/Changelog.txt/download">Les modifications</a> représentent principalement des corrections d'anomalies.</p> <br />
<p> </p> <br />
<p>Une nouveauté intéressante pour les utilisateurs sous Linux : sur la sélection d'un fichier, il est désormais possible d'ouvrir ce fichier ou le répertoire le contenant directement à partir de FreeFileSync, le tout compatible avec (presque) toutes les distributions Linux.</p> <br />
<p align="center"><img width="539" height="331" class="serendipity_image_center" style="border: 0px none; padding-left: 5px; padding-right: 5px;" src="http://www.dlecan.com/uploads/screenshot_008.png" alt="" /></p> <br />
<p> </p> <br />
<p>Cette fonction utilise le programme <em>xdg-open</em>, fourni indirectement par le projet freedesktop.org. Si vous êtes développeurs Linux, jettez un coup d'oeil à <a href="http://portland.freedesktop.org/xdg-utils-1.0/">la documentation</a>, on y trouve des outils intéressants. <br /></p> <br />
<p>Si vous avez mis à jour FreeFileSync 3.7 depuis la version 3.6, vous devez réinitialiser vos paramètres généraux pour en bénéficier (menu <em>Avancé => Paramètres Généraux ... => Défaut</em>). </p> <br />
<p> </p>
FreeFileSync 3.6
2010-05-10T00:00:00+00:00
2010-05-10T00:00:00+00:00
https://dlecan.com/blog/freefilesync-3-6/
<p>FreeFileSync 3.6 pour Ubuntu est disponible depuis quelques semaines déjà. Les utilisateurs du PPA sont déjà à jours depuis longtemps <img src="http://www.dlecan.com/templates/default/img/emoticons/wink.png" alt=";-)" style="display: inline; vertical-align: bottom;" class="emoticon" /> Les autres pourront suivre la <a href="http://doc.ubuntu-fr.org/freefilesync">procédure d'installation en français</a>.<br /></p> <br />
<p>En dehors des <a href="https://sourceforge.net/projects/freefilesync/files/freefilesync/v3.6/Changelog.txt/download">nouveautés de FFS lui-même</a>, je prépare le paquet Ubuntu à l'internationalisation via <a href="https://translations.launchpad.net/freefilesync">l'outil d'aide à la traduction de Launchpad</a>. <br /></p>
How to install FreeFileSync on Ubuntu (PPA) (Edited)
2010-05-10T00:00:00+00:00
2010-05-10T00:00:00+00:00
https://dlecan.com/blog/how-to-install-freefilesync-on-ubuntu-ppa-edited/
<p>This is a step-by-step procedure for installing FreeFileSync on Ubuntu, aimed at beginners or users who rarely worked with PPAs (Personal Package Archives) before.</p> <br />
<p>Please note: this guide applies to Ubuntu Karmic (9.10), Lucid (10.04), Maverick (10.10) and later versions.<br /></p> <br />
<ol> <br />
<li>Add FreeFileSync PPA to your Software Sources<br />Navigate to <em>System</em> ▸ <em>Administration</em> ▸ <em>Software Sources</em></li> <br />
<li>Navigate to the <em>Third Party Software</em> tab and hit the <em>Add...</em> button. <br /></li> <br />
<li>Paste <em>ppa:freefilesync/ffs</em> into the entry box of the following popup to add our repository to the list of software sources. Then click on <em>Add Source</em>. Close the window.<br /></li> <br />
<li>When prompted to Reload the information about available software press <em>Reload</em> and wait for the operation to complete. <br /></li> <br />
<li>Now, just <a title="Install FreeFileSync" href="apt://freefilesync">install FreeFileSync</a><br /></li> <br />
<li>After the end of the installation process, you can start FreeFileSync for the first time using the menu entry <em>Applications</em> ▸ <em>Accessories</em> ▸ <em>FreeFileSync</em></li> <br />
</ol> <br />
<p>Expert users, you can visit <a href="https://launchpad.net/~freefilesync/+archive/ffs">FreeFileSync PPA page</a> or<a href="https://launchpad.net/~freefilesync"> FreeFileSync maintenance team page</a> if needed (translations, package information, ...).</p> <br />
<p><strong>Note (2010-05-10)</strong>: FreeFileSync 3.6 will be the last version available for Ubuntu Karmic 9.10. Upgrade to Ubuntu Lucid 10.04 to get last version of FFS.<br /></p>
Bilan de migration vers Ubuntu 10.04
2010-05-06T00:00:00+00:00
2010-05-06T00:00:00+00:00
https://dlecan.com/blog/bilan-de-migration-vers-ubuntu-10-04/
<p>Je viens de migrer 3 PC que je gère de Ubuntu 9.10 vers Ubuntu 10.04. Globalement, tout s'est bien déroulé, je suis content des outils de migration de Canonical.</p> <br />
<p>Voici les différences/problèmes que j'ai rencontré et comment je les ai résolus :</p> <br />
<ul> <br />
<li>Migration partielle du thème graphique</li> <br />
</ul> <br />
<p>Alors que j'utilise partout le thème par défaut, la migration vers les nouveaux thèmes Ambiance ou Radiance ne s'effectue que partiellement : nouvelles icônes, mais anciennes couleurs par exemple.</p> <br />
<p>Un passage dans <em>Système</em>=><em>Préférences</em>=><span style="font-style: italic;">A</span><em>pparence</em>=><em>Thème </em>et une sélection du thème Ambiance ou Radiance rétablit la situation.</p> <br />
<ul> <br />
<li>Nouvelle gestion de l'ouverture des onglets dans Firefox 3.6</li> <br />
</ul> <br />
<p>Dans Firefox 3.6, les onglets ouverts sur un lien s'ouvrent désormais juste à côté de l'onglet courant. Cela permet de garder les onglets d'un même contexte groupés.</p> <br />
<p>Intéressant, mais habitué à l'ancien comportement, je l'ai rétabli en <a href="http://protuts.net/restaurer-comportement-ouverture-onglets-firefox-3/">suivant cette procédure</a>.</p> <br />
<ul> <br />
<li>Préférence des "Effets visuels"</li> <br />
</ul> <br />
<p>J'ai eu régulièrement des soucis avec cette préférence, qui change de valeur un peu comme elle veut en fonction des machines.</p> <br />
<p>Sur ma machine professionnelle, avec des pilotes graphique NVidia propriétaires (carte vidéo mobile trop récente), je n'ai jamais réussi à l'activer sur Ubuntu Karmic 9.10. Mais maintenant cela fonctionne sur Ubuntu Lucid 10.04 <img src="http://www.dlecan.com/templates/default/img/emoticons/smile.png" alt=":-)" style="display: inline; vertical-align: bottom;" class="emoticon" />.</p> <br />
<p>En revanche, sur mes deux autres machines (carte vidéo Intel et ancienne NVidia), tout fonctionnait très bien sur Ubuntu Karmic. Alors qu'avec Ubuntu Lucid les effets visuels sont désactivés à chaque fermeture de session. Je dois les réactiver manuellement. Pas de solution pour le moment, c'est juste ennuyant.</p> <br />
<ul> <br />
<li>Impossible d'utiliser UbuntuOne ou Gwibber</li> <br />
</ul> <br />
<p>Sur une de mes machines, UbuntuOne ou Gwibber (mais sûrement d'autres programmes sont affectés aussi) ne fonctionnent pas. Un obscur problème avec le gestionnaire de clés. Plusieurs problème de ce genre sont déjà rapportés sur Launchpad, on verra ce qu'il en sort.<br /></p> <br />
<p>Je contourne temporairement le problème en lançant manuellement <em>gnome-keyring-daemon</em>.</p> <br />
<ul> <br />
<li>GeoGebra et OpenJDK</li> <br />
</ul> <br />
<p>Officiellement, la machine virtuelle Java Sun/Oracle n'est plus disponible sur Ubuntu, remplacée par sa version libre OpenJDK. Globalement, les applications Java fonctionnent bien avec cette autre machine virtuelle.</p> <br />
<p>Cependant, les <a href="http://www.slu.edu/classes/maymk/GeoGebra/">applets GeoGebra ne fonctionnent pas</a> avec pour le moment (solution : retour à une JVM Sun/Oracle standard en <a href="https://bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/440841">attendant un correctif</a>).<br /> </p> <br />
<p><strong>Ce que je retiens de cette migration</strong></p> <br />
<ul> <br />
<li>La migration s'est parfaitement déroulée avec un PC qui avait été installé avec la version <em>n-1</em> par rapport à Ubuntu 10.04,</li> <br />
<li>La migration s'est correctement déroulée, avec quelques soucis mineurs, sur un PC installé avec la version <em>n-3</em>, migré en <em>n-2</em>, ... jusqu'à la version 10.04,</li> <br />
<li>La plus mauvaise migration s'est faite <br />
sur un PC installé avec la version <em>n-4</em>, migré jusqu'à la version 10.04.</li> <br />
</ul>J'ai l'impression qu'avec le temps, les migrations se déroulent de moins en moins bien, cela étant probablement dû à l'accumulation de résidus de préférences utilisateurs.<br />
Recherche d'un remplaçant à Unison (2/2)
2010-03-18T00:00:00+00:00
2010-03-18T00:00:00+00:00
https://dlecan.com/blog/recherche-dun-remplacant-a-unison-22/
<p><a href="http://www.dlecan.com/archives/55-Recherche-dun-remplacant-a-Unison-12.html">Ma recherche d'un outil de synchronisation de fichiers intégré à Ubuntu n'ayant rien donné</a>, je me suis résigné à chercher un outil non empaqueté pour Ubuntu, avec l'espoir, soit d'en trouver un multi-plateforme, ce qui augmente sa communauté d'utilisateurs et donc sa pérennité (mais sans aucune garantie dans le temps effectivement), soit uniquement dédié à Ubuntu.<br /></p> <br />
<p>Je trouve rapidement <a href="http://en.wikipedia.org/wiki/File_synchronization">une page sur Wikipedia</a> qui liste quelques produits open-source et multi-plateforme. Parmi les huit candidats, six semblent multi-plateforme, et parmi ceux-ci deux sortent du lot : <a href="http://synkron.sourceforge.net/index.php">Synkron</a> et <a href="http://sourceforge.net/projects/freefilesync/">FreeFileSync</a>, que je teste immédiatement.</p> <br />
<ul> <br />
<li> Synkron </li> <br />
</ul> <br />
<div align="justify"> <br />
<p>L'interface de l'outil est sympathique, les fonctionnalités au rendez-vous et il est disponible en français. Des binaires sont disponibles pour Windows, Mac OS et, avec un peu de recherche, aussi pour Linux sous forme de RPM (pour Mandriva par exemple) ou DEB (pour Ubuntu ou Debian). Il est à noter que les paquets pour Linux sont un peu en retard sur les autres.</p> <br />
<p>Un des avantages de Linux est de ne pas à faire soi-même les mises à jour, et, même si les outils peuvent embarquer en interne un système de mise à jour, il est nettement plus efficace qu'un logiciel soit disponible dans un dépôt plutôt qu'en téléchargement quelque part. Les mises à jour sont automatiques et automatisées pour l'utilisateur.</p> <br />
<p>Je recherche donc un PPA Ubuntu ou un effort d'intégration dans les dépôts officiels Ubuntu. Je trouve <a href="https://launchpad.net/%7Esportman1280/+archive/ppa">ce PPA</a>, mais Synkron n'y est plus mis à jour. Je trouve aussi <a href="http://revu.ubuntuwire.com/details.py?upid=3821">une page REVU témoignant de l'effort d'intégration</a> de Synkron dans Ubuntu, mais qui n'a pas abouti.</p> <br />
<p> <u>Bilan</u> : un outil intéressant, mais disponible sur Ubuntu <em>à-la-Windows</em> (installe et mets à jour toi-même).</p> <br />
<ul> <br />
<li>FreeFileSync</li> <br />
</ul> <br />
<p>En français, l'interface est un peu moins professionnelle que celle de Synkron, mais elle me plaît immédiatement. Les options avancées sont masquées par défaut à l'utilisateur, ce qui correspond bien à mon besoin d'un outil simple et compréhensible.</p> <br />
<p>Il est multi-plateforme Windows, Mac OS et Linux mais réellement empaqueté seulement pour Windows et Mac OS. Linux doit se contenter de binaires "portables", c'est-à-dire que l'installation s'effectue par extraction d'un fichier zip : idéal pour une clé USB mais pas de paquet DEB.</p> <br />
<p>La lecture du forum m'apprend qu'un paquet deb est régulièrement demandé, mais sans succès.</p> <br />
<p> <u>Bilan</u> : un outil prometteur qui mériterait d'être empaqueté pour Ubuntu.</p> <br />
<p> </p> <br />
<p>N'ayant aucune connaissance en création de paquet pour Ubuntu, je me suis dit que c'était l'occasion idéale d'apprendre. <em>Let's go</em> pour <a href="http://sourceforge.net/projects/freefilesync/">FreeFileSync</a>, empaqueté pour Ubuntu !<br /></p> <br />
</div>
Recherche d'un remplaçant à Unison (1/2)
2010-02-16T00:00:00+00:00
2010-02-16T00:00:00+00:00
https://dlecan.com/blog/recherche-dun-remplacant-a-unison-12/
<p><a href="http://www.dlecan.com/archives/54-Remplacer-Unison.html">Unison devant être remplacé</a>, je me suis lancé dans la recherche d'un nouvel outil.<br />
<br />
Je me suis fixé les critères de recherche suivant, par ordre décroissant d'importance :<br /></p>
<ul><br />
<li>Fonctionne sous Linux, idéalement déjà empaqueté pour Ubuntu</li><br />
<li>Disponible en français</li><br />
<li>Simple à utiliser, <em>à la Windows</em> je serais tenter de dire ; c'est-à-dire qu'un utilisateur normal doit pouvoir comprendre tous les concepts qui lui sont présentés (fat32 ? gestion des droits ? timestamps ? A proscrire, ou alors dans des préférences bien cachées)</li><br />
<li>Présentant les différences entre la source et la destination de manière claire</li><br />
<li>Présentant les modifications qui vont être appliquées (comme dans Unison)</li><br />
</ul><br />
<br />
Un petit tour dans la logithèque Ubuntu me donne de bons candidats :<br />
<ul><br />
<li><a href="http://www.opbyte.it/grsync/">grsync</a> (<a href="apt://grsync" title="Installer sur Ubuntu">installer</a>) : interface graphique utilisant <a href="http://doc.ubuntu-fr.org/rsync">rsync</a>. Très puissant, mais trop compliqué (cases à cocher incompréhensibles pour un utilisateur "normal")</li><br />
<li><a href="http://luckybackup.sourceforge.net/">luckybackup</a> (<a href="apt://luckybackup" title="Installer sur Ubuntu">installer</a>) : même principe que Grsync : trop compliqué</li><br />
<li>Komparator : plutôt pour Xubuntu</li><br />
<li>Quelques autres outils de synchronisation de données applicatives (calendrier, emails, notes, ...) plutôt que de fichiers : Conduit, Multisync...</li><br />
</ul><br />
<br />
Si je croise ces candidats avec ma liste d'exigence, il ne me reste ... rien <img src="http://www.dlecan.com/templates/default/img/emoticons/sad.png" alt=":-(" style="display: inline; vertical-align: bottom;" class="emoticon" />. Il va falloir que je trouve mon outil autre part.
Remplacer Unison
2010-01-30T00:00:00+00:00
2010-01-30T00:00:00+00:00
https://dlecan.com/blog/remplacer-unison/
<p>J'utilise depuis pas mal de temps <a href="http://doc.ubuntu-fr.org/unison" title="Doc Ubuntu pour Unison">Unison</a> pour synchroniser mes clés USB avec un répertoire local sous Ubuntu.<br />
<br />
L'outil fonctionne bien, répond à mes besoins. Mais quel est le problème alors ?<br />
<br />
Dans ma famille, il n'y a que moi qui réussisse à l'utiliser parce qu'il a quand même de gros défauts, que j'énumère par la suite.<br />
<br /></p>
<ul><li><strong>L'interface est en anglais exclusivement</strong></li></ul><br />
Ca ne dérange pas vraiment, mais je comprends que ça puisse être un frein à son utilisation, malgré la bonne documentation du site <a href="http://doc.ubuntu-fr.org/unison" title="Doc Ubuntu pour Unison">Ubuntu-fr</a>.<br />
Après quelques recherches, Unison n'est apparemment pas disponible dans d'autres langues.<br />
<br />
Je me dis que c'est de l'open-source et que je n'ai qu'à le traduire moi-même. Un petit tour sur le site originel d'<a href="http://www.cis.upenn.edu/~bcpierce/unison/" title="Site d'Unison">Unison</a> me permet de télécharger le code source et de tomber sur de ... l'OCaml ?!?!<br />
<a href="http://fr.wikipedia.org/wiki/Objective_Caml">Wikipedia</a> me dit que c'est un super langage de programmation, mais que je ne connais pas.<br />
<br />
Je finis par tomber le fichier qui programme l'interface : ~4300 lignes de code !<br />
Toute l'interface en un seul fichier. OCaml c'est bien apparemment, mais la mise en oeuvre sur l'interface pourrait être améliorée.<br />
<br />
Visiblement, rien a été prévu pour gérer l'internationalisation de l'interface, je laisse tomber.<br />
<br />
<ul><li><strong>L'interface est particulièrement limitée et ne représente absolument les fonctionnalités de l'outil</strong></li></ul><br />
L'interface graphique d'Unison ne permet pas de configurer la façon dont les synchronisations vont s'effectuer. Il faut passer par l'édition d'un fichier texte avec <a href="http://wiki.mandriva.com/fr/unison">la doc sous la main</a>, mais impossible de donner ça à ma famille.<br />
<br />
Et faire évoluer l'interface est bien plus difficile que de la traduire, tâche que j'ai abandonnée ...<br />
<br />
Il est vraiment temps de trouver un remplaçant !
Ahh, les Iles Lofoten (tout là-haut, dans le Grand Nord)
2009-09-16T00:00:00+00:00
2009-09-16T00:00:00+00:00
https://dlecan.com/blog/ahh-les-iles-lofoten-tout-la-haut-dans-le-grand-nord/
<p>Seulement trois jours aux Iles Lofoten, c'est beaucoup trop court.<br />
Mais quel bonheur ! Les paysages, la lumière, tout est y magnifique. Je crois me souvenir que le Routard qualifie les Iles Lofoten du plus bel endroit du plus beau pays du monde.<br />
Haut la main ...<br />
<br />
Un petit panorama pour la route :<br />
<a href="http://picasaweb.google.com/lh/photo/pnO7jn-pGwR9IKlq6mtYtA?feat=embedwebsite"><img src="http://lh5.ggpht.com/_YRLPyKcp69o/SrC5Dq1u5EI/AAAAAAAAAC8/TwGWUWtrZJw/s400/2007-07-29%2012-35-13%20-%20Vacances%20Su%C3%A8de-Norv%C3%A8ge-pano.jpg" alt="" /></a></p>
Une belle photo de Lyon
2009-08-28T00:00:00+00:00
2009-08-28T00:00:00+00:00
https://dlecan.com/blog/une-belle-photo-de-lyon/
<p>Lyon, par une froide matinée de Février 2008 ...<br />
<br />
<a href="http://picasaweb.google.com/lh/photo/HEfAieyJlro8XpUsQdKiRQ?feat=embedwebsite"><img src="http://lh4.ggpht.com/_YRLPyKcp69o/Spf4ZN94QoI/AAAAAAAAACU/PEDBHFJo6aA/s400/2008-01-28%2009-42-34%20-%20WE%20Lyon%20-%20pano.jpg" alt="" /></a></p>
Point sur l'Euro
2007-11-24T00:00:00+00:00
2007-11-24T00:00:00+00:00
https://dlecan.com/blog/point-sur-leuro/
<p>Rappelez-vous, l'introduction de l'<a href="http://fr.wikipedia.org/wiki/Zone_euro" title="Euro sur Wikipedia">Euro</a> remonte déjà à presque 6 ans.<br />
12 pays au départ (France, Allemagne, Belgique, Pays-Bas, Italie, Espagne, Portugal, Grèce, Finlande, Irlande, Luxembourg, Autriche) rejoints au 1er janvier dernier par la Slovénie.<br />
D'autres pays, comme Chypre, Malte ou la Slovaquie, ayant été accueillis récemment dans l'Union Européenne, adopteront l'Euro en 2008 ou en 2009.<br />
<br />
Je suis toujours avec attention toute l'actualité convernant les discussions ou les tentatives de passage l'Euro des trois pays "historiques" qui résistent cependant à la monnaie européenne : le Danemark, la Suède et le Royaume-Unis.<br />
<br />
Passons le cas du Royaume-Unis qui possède une dérogation permanente au passage à l'Euro et dont la population est particulièrement eurosceptique.<br />
<br />
La suède a déjà refusé largement l'Euro une première fois en 2003, mais ce n'est qu'une question de temps, l'exemple de la Finlande proche montrant aux Suédois que ce changement de monnaie peut-être très profitable. A noter cependant que la couronne Suédoise a perdu beaucoup de sa valeur ces dernières années, rendant moins intéressant un éventuel changement. Pour le moment.<br />
<br />
Enfin, le Danemark a lui aussi déjà rejeté la monnaie unique en 2000. Mais le gouvernement en place <a href="http://www.euractiv.fr/avenir-de-lue/article/danemark-pourrait-bientot-choisir-euro-00518" >semble être prêt</a> à organiser une nouvelle consultation populaire dans les années à venir.<br />
<br />
De bonnes nouvelles donc !</p>
Nouveau traité pour l'Europe
2007-06-25T00:00:00+00:00
2007-06-25T00:00:00+00:00
https://dlecan.com/blog/nouveau-traite-pour-leurope/
<p>Finalement, je n'irais pas jusqu'au bout de mon billet sur le <a href="http://www.dlecan.com/archives/20-Bilan-des-ratifications.html" title="Bilan des ratifications">bilan des ratifications de la Constitution européenne</a>.<br />
<br />
Les 27 pays membres de l'Union Européenne sont enfin parvenus à un accord sur un traité "simplifié" permettant de débloquer le fonctionnement des institutions européennes.<br />
<br />
Parmis les points importants, on peut noter :<br /></p>
<ul>
<li>Votes dans les conseils européens à la double majorité des Etats et de la population<br /></li>
<li>Pas de référence à la "concurrence libre et non faussée" comme objectif de l'Union européenne<br /></li>
<li>Mention de la "protection des citoyens" parmi les tâches de l'Europe<br /></li>
<li>Non application de la Charte Européenne des droits fondamentaux aux britaniques (pourquoi ??)<br />
<br />
Le nouveau traité reprendra les principales dispositions institutionnelles de la Constitution, telles la présidence stable ou la création d'un responsable de la diplomatie doté de pouvoirs accrus.<br />
<br />
Enfin, ce système, qui n'entrera en vigueur que progressivement entre 2014 et 2017, devra être ratifié avant 2009 (référendum ou pas ?).<br />
<br />
<a href="http://bruxelles.blogs.liberation.fr/coulisses/2007/06/une-constitutio.html" >Plus d'information sur les négociations</a> sur cet excellent site.<br /></li>
</ul>
Bilan des ratifications
2006-12-05T00:00:00+00:00
2006-12-05T00:00:00+00:00
https://dlecan.com/blog/bilan-des-ratifications/
<p>Voici un bilan des différentes ratifications de constitution européenne pour les pays ayant recours au référendum. Il est évident que les parlements des autres pays voteront "oui".<br />
<br />
Pour le moment, le "non" aux référendums l'emporte largement.<br />
<br />
<b>Effectués</b> :<br />
Espagne (consultatif) le 20/02/2005 : "oui" à 77%<br />
France le 29/05/2005 : "non" à 55% (70% de participation)<br />
Pays-Bas (consultatif) le 01/06/2005 : "non" à 62% (63% de participation)<br />
<br />
Pas d'autres référendums pour le moment !<br />
<br />
<b>A venir</b> :<br />
République tchèque<br />
<br />
<b>Reportés</b> :<br />
Danemark<br />
Pologne<br />
Royaume-Uni (consultatif)<br />
Irlande<br />
Portugal<br />
Suède</p>
D'où viennent les euros de nos poches ?
2006-08-06T00:00:00+00:00
2006-08-06T00:00:00+00:00
https://dlecan.com/blog/dou-viennent-les-euros-de-nos-poches/
<p><a href="http://www.eurobilltracker.com/">On pouvait déjà suivre</a> le trajet des billets en euro à travers l'Europe mais à l'initiative de chacun d'entre nous. Cette fois-ci, c'est <a href="http://www.esdo.prd.fr/">une étude très sérieuse</a> qui nous montre la circulation des pièces au sein de l'Europe après que des spécialistes aient analysés nos porte-monnaie.<br />
<br />
C'est centré sur la France, dommage, mais <a href="http://www.esdo.prd.fr/sites.html">d'autres sites</a> nous permettent de voir ces mêmes diffusions dans d'autres pays d'Europe.</p>
Chine au galop
2005-12-24T00:00:00+00:00
2005-12-24T00:00:00+00:00
https://dlecan.com/blog/chine-au-galop/
<p>Ce qui devait arriver arrive ... beaucoup plus vite que prévu !<br />
<br />
La Chine est <a href="http://permanent.nouvelobs.com/economie/20051220.OBS9430.html">en passe de devenir la 4è puissance mondiale</a>, au détriment de la France et de la Grande-Bretagne.<br />
<br />
Les calculs n'ont pas l'air simples ...</p>
Reporters globe-trotters
2005-11-29T00:00:00+00:00
2005-11-29T00:00:00+00:00
https://dlecan.com/blog/reporters-globe-trotters/
<p>"<a href="http://www.radiofrance.fr/chaines/france-info/dossiers/info/index.php?rid=235000233">France Info en Inde</a>", c'est cette semaine, chaque matin.<br />
France Info avait déjà fait une expérience de <a href="http://www.radiofrance.fr/chaines/france-info/dossiers/info/index.php?rid=235000116">radio en directe de Chine</a>, et j'avais trouvé le concept excellent. Une équipe de reporters parcourt le pays et aborde différents thèmes à chaque étape. Rafraichissant !</p>
Sportifs de chambre
2005-11-14T00:00:00+00:00
2005-11-14T00:00:00+00:00
https://dlecan.com/blog/sportifs-de-chambre/
<p>Durex vient de publier son rapport annuel sur le sexe et les pratiques sexuelles des hommes et des femmes. <a href="http://www.durex.com/uk/globalsexsurvey/2005results.asp">Ce rapport</a> est assez complet puisqu'il analyse le comportement 317 000 personnes dans 41 pays.<br />
<br />
Tous les médias n'ont retenu qu'une chose : que les français ont perdu la première place du pays le plus "sexy", <i>i.e.</i> le pays qui dont les habitants ont le plus de rapports sexuels à l'année. Ce sont les grecs qui sont les meilleurs en sport de chambre, avec 138 rapports par an (un tous les 2,5 jours). Les français n'ont "que" 120 rapports par an (un tous les 3 jours).<br />
<br />
On peut voir dans la rubrique <i>Sexual experience you've had</i> que la morale des américains ne les empêchent pas du tout de s'amuser, et ce, de manière très variée ... <i>Faites ce que je dis, pas ce que je fais </i>;o)</p>
Podium d'exécuteurs : Chine, Iran et Vietnam
2005-10-21T00:00:00+00:00
2005-10-21T00:00:00+00:00
https://dlecan.com/blog/podium-dexecuteurs-chine-iran-et-vietnam/
<p>Hop, encore un <a href="http://www.handsoffcain.org/bancadati/index.php?tipotema=arg&idtema=6000633">rapport annuel</a> (c'est la saison), concernant cette fois-ci la <a href="http://www.revoltes.org/">peine de mort dans le monde</a>.<br />
<br />
Les nouvelles sont plutôt bonnes, puisque globalement l'application de la peine de mort recule dans le monde. Officiellement, 5523 personnes ont été exécutées (-1,5% par rapport à 2003) et 3 nouveaux pays ont renoncé à l'appliquer (58 en 2005 contre 61 en 2003 et 64 en 2002).<br />
La Chine explose le compteur des exécutions, puisque qu'elle totalise à elle seule plus de 90% des exécutions. Suivent l'Iran et la Chine.<br />
<br />
Même si 76% des pays qui appliquent la peine de mort sont répertoriés comme des dictatures ou des régimes/démocraties autoritaires, les démocraties "libres" appliquent aussi la peine de mort. Parmis celles-ci, les Etats-Unis, Tawain, le Japon ou l'Inde.</p>
Corruption : chez nous aussi !
2005-10-18T00:00:00+00:00
2005-10-18T00:00:00+00:00
https://dlecan.com/blog/corruption-chez-nous-aussi/
<p>Quand on parle de corruption, on pense facilement à un homme (policier ?) qui arrondit ses fins de mois en fermant les yeux sur certains trafics. Tout le monde s'y retrouve et tout le monde est content.<br />
<br />
Ce type de comportement n'est pas très courant dans nos pays occidentaux, ce qui nous amène rapidement à conclure que la corruption est un phénomène marginal. Mais voilà, il y a aussi la corruption de haut vol, celle qui détourne des millards d'euros.<br />
<br />
C'est ce que montre le rapport annuel de <a href="http://www.transparency.org/">Transparency International</a>. Selon cette organisation non gouvernementale dédiée à la lutte contre la corruption, la France n'est qu'au 18è rang mondial, 12e rang européen en 2005.<br />
Les pays nordiques font beaucoup mieux (encore !), les pays du sud de l'Europe montrent que la corruption n'est pas réservée aux pays à bas revenus.<br />
<br />
<a href="http://www.globalcorruptionreport.org/download_fr.html">Rapport 2005 <strong>complet</strong></a> de Transparency International à télécharger.<br />
<a href="http://www.transparency.org/cpi/2005/2005.10.18.cpi.fr.html">Un résumé est disponible en français</a>, avec le <a href="http://www.transparency.org/cpi/2005/2005.10.18.cpi.fr.html#cpi">classement</a>.</p>
Moins de guerres
2005-10-18T00:00:00+00:00
2005-10-18T00:00:00+00:00
https://dlecan.com/blog/moins-de-guerres/
<p>Selon l'étude "Guerre et paix au XXIe siècle", le nombre de conflits armés a été réduit de 40 % depuis 1992.<br />
Ce qui paraît vraiment étonnant en regardant nos journaux chaque jours, télévisés ou pas. On a la "désagréable" (sic !) impression que cela ne s'améliore pas avec le temps.<br />
<br />
L'<a href="http://www.lemonde.fr/web/article/0,1-0@2-3220,36-700474@51-700625,0.html">article du Monde</a> pour cette info.</p>
Milliard(s) d'abonnés
2005-09-19T00:00:00+00:00
2005-09-19T00:00:00+00:00
https://dlecan.com/blog/milliards-dabonnes/
<p>Presqu'<a href="http://www.journaldunet.com/cc/01_internautes/inter_nbr_mde.shtml">un milliard d'abonnés à Internet</a>, presque <a href="http://www.neteco.com/article_20050919102815_.html">2 milliards pour le téléphone portable</a>, ça en fait des communications et des données <a href="http://www.cite-sciences.fr/webmag/mai/webmagazine/reperes/pages/repe05.htm">à surveiller</a> ça ...</p>
Langues de machos
2005-08-26T00:00:00+00:00
2005-08-26T00:00:00+00:00
https://dlecan.com/blog/langues-de-machos/
<p><a href="http://www.cybersciences.com/Cyber/3.0/N3403.asp">Les langues disparaissent plus vite que les espèces animales</a>, j'ai du mal à la croire. Etant donné la catastrophe qui s'annonce au niveau des espèces végétales et animales, c'est un ouragan/tsunami/tremblement de terre qui doit être en train de ravager les langues humaines!<br />
<br />
<a href="http://portal.unesco.org/culture/fr/ev.php-URL_ID=8270&URL_DO=DO_TOPIC&URL_SECTION=201.html">Selon l'Unesco</a> :<br /></p>
<ul><br />
<li>Plus de 50% des 6000 langues du monde sont en danger de disparition</li><br />
<li>96% des 6000 langues au monde sont parlées par 4% de la population mondiale</li><br />
<li>90% des langues au monde ne sont pas représentées sur Internet</li><br />
<li>1 langue disparaît en moyenne toutes les deux semaines</li><br />
<li>80 % des langues africaines nont pas de transcription écrite</li><br />
</ul><br />
Inquiétant tout ça.<br />
<br />
Mais après tout, les langues suivent l'évolution des cultures et leur rayonnement. Les Etats-Unis dominent économiquement la planète et ont largement imposé l'anglais. On peut faire le pari (sans trop délirer) que le chinois sera une langue incontournable d'ici la fin du siècle, au même titre que l'anglais aujourd'hui.<br />
Le latin a bien disparu avec la chute de l'empire romain, mais la culture associée a perduré au travers des langues latines qui en découlent (français, italien, roumain, ...).<br />
<br />
Parmi toutes ces langues qui disparaissent, peu laissent des traces suffisantes pour maintenir la culture associée, qui disparaissent alors à jamais.<br />
<br />
Revenons-en à nos langues de machos, le sujet de ce billet. La culture fait la langue, la langue fait la culture, difficile de savoir qui est l'oeuf ou la poule, les deux sont intimement liés. Prenons un exemple simple, en français.<br />
J'ai toujours entendu pendant la scolarité, "le masculin l'emporte" (évidemment, c'est d'orthographe dont je parle ;o)).<br />
<blockquote>Un homme et un milliard de femmes sont heureux.</blockquote><br />
Si c'était le nombre qui l'emportait, toutes ces personnes seraient heureuses, mais le français décide autrement. Comment ne pas être influencé par une telle phrase, que l'on entend depuis son plus jeune âge, une fois adulte ? La langue entretient des comportements, qui à leur tour, façonnent et orientent la langue. On se rappelle les tentatives récentes de féminisation des mots de la langue française en espérant qu'un jour ces mots influenceront différemment les esprits.<br />
<br />
Quand je réfléchis à ça, je pense souvent au pauvre "das Mädchen" (la fille) allemand, qui est du genre neutre. On ne peut pas faire pire je trouve ...
Rentrée des classes
2005-08-23T00:00:00+00:00
2005-08-23T00:00:00+00:00
https://dlecan.com/blog/rentree-des-classes/
<p>L'activité médiatique a été au plus bas pendant quelques semaines, mais le monde ne s'est pas arrêté pour autant : la Chine a continué à monter en puissance, les prix du pétrole ont poursuivi leur explosion. En bref, rien de bien nouveau.<br />
<br />
Pour cette rentrée, j'attends les chiffres de la <a href="http://www.banquemondiale.org/EXT/French.nsf/DocByUnid/34A9F43D563CEA2085256D71006AE08F?Opendocument">Banque Mondiale</a> de 2004 pour mettre à jour <a href="http://www.dlecan.com/archives/16-La-Chine-plus-tres-loin-de-la-5e-place.html">ma comparaison</a>.<br />
J'essaie de préparer une comparaison des pays qui peuvent couvrir à eux seuls toutes les activités humaines : le Brésil (secteur primaire), la Chine (secteur secondaire) et l'Inde (secteur tertiaire). J'ajouterai la France et les Etats-Unis dans les graphiques si ça ne dérègle pas trop les échelles ;o)<br /></p>
Touristes du monde
2005-08-23T00:00:00+00:00
2005-08-23T00:00:00+00:00
https://dlecan.com/blog/touristes-du-monde/
<p>Je suis vraiment étonné du nombre de touristes que j'ai pu rencontré à Nantes cet été : des anglais, des allemands, des italiens, des espagnols, ... Peut-être que la pub indirecte du Times de Londres (c'est le magazine qui a déclaré que Nantes est la ville la plus agréable d'Europe) commence à porter ses fruits.<br />
<br />
Pour savoir pourquoi il y a tant de touristes à Nantes, il me faudra attendre l'année prochaine, seuls les chiffres 2004 sont disponibles pour le moment (<a href="http://www.world-tourism.org/francais/">OMT</a> ou <a href="http://www.tourisme.gouv.fr/">Ministère du Tourisme français</a>).<br />
<br />
A partir du <a href="http://www.world-tourism.org/facts/eng/pdf/barometer/WTO_Barom05_2_excp_fr.pdf">bilan de l'OMT</a> sur l'année 2004, on découvre que les américains sont les champions de l'incitation à la dépense dans leur pays. Jugez vous-même :<br /></p>
<ul><br />
<li>Etats-Unis : 1808,25 $/touriste international (<strong>74,5M$</strong> pour 41,2 millions de touristes)</li><br />
<li>Espagne : 872,59 $/touriste international (45,2M$ pour 51,8 millions de touristes)</li><br />
<li>France : 543,28 $/touriste international (40,8M$ pour <strong>75,1 millions</strong> de touristes)</li><br />
</ul><br />
Malgré notre arrogance, beaucoup de touristes viennent en France, mais rechignent à dépenser.<br />
<br />
En voyant ces chiffres, on peut se demander s'ils tiennent compte des touristes "locaux" où s'ils ne prennent en compte que les touristes "étrangers".<br />
<br />
Au sens de l'OMT, <blockquote>est considérée comme touriste toute personne en déplacement hors de son environnement habituel pour une durée d'au moins une nuitée et dau plus un an, pour des motifs non liés à une activité rémunérée dans<br />
le lieu visité. Sera comptée comme arrivée de touriste international dans un pays donné, toute visite d'une personne ne résidant pas dans ce pays et venant y passer au moins une nuitée. Par exemple, un touriste américain visitant l'Europe sera comptabilisé chaque fois quil entre dans un des états dEurope. Un touriste français visitant New York, la Californie et la Floride ne sera comptabilisé qu'une seule fois, à son entrée aux États-Unis.</blockquote> (extrait de "<a href="http://www.tourisme.gouv.fr/fr/z2/stat/chiffres/att00009212/cles2005_fr.pdf">Chiffres clés du tourisme</a>", Direction du Tourisme, 2005).<br />
<br />
Les chiffres donnés plus haut ne prennent en compte que les touristes internationaux.<br />
<br />
Je ne l'ai pas encore précisé, mais la Chine arrive désormais en 4è position pour le nombre de touristes internationaux accueillis (41,8 millions de touristes), en augmentation de 26,7% par rapport à 2003. L'Asie attire ...
1, 2, 3 ... 6,5
2005-07-18T00:00:00+00:00
2005-07-18T00:00:00+00:00
https://dlecan.com/blog/1-2-3-6-5/
<p>6,5 milliards, c'est le nombre record d'habitants que la Terre accueille en 2005 : un milliard d'habitants en 1800, deux milliards en 1930, trois en 1960, quatre en 1974, cinq en 1987, six en 1999.<br />
Les projections sont pessimistes -9 millards en 2050- même si la croissance ne sera pas aussi forte au XXIè siècle que dans le siècle passé.<br />
Vieillissement des populations des pays riches, aussi bientôt des pays du Sud, comment gérer ces situations pendant le XXIè siècle ?<br />
<br />
Les démographes du monde <a href="http://www.iussp.org/France2005/">sont réunis</a> pendant une semaine pour en débattre.<br />
<br /></p>
Dans quelle ville du monde en avoir pour son argent ?
2005-06-23T00:00:00+00:00
2005-06-23T00:00:00+00:00
https://dlecan.com/blog/dans-quelle-ville-du-monde-en-avoir-pour-son-argent/
<p>Apparemment, on en a plus pour son argent à vivre à Amsterdam qu'à Douala (Cameroun !) selon <a href="http://www.mercerhr.com/pressrelease/details.jhtml/dynamic/idContent/1142150">une étude comparative du coût de la vie</a> des principales villes mondiales.<br />
<br />
On y découvre que les villes nord-américaines sont plutôt abordables et qu'il faut absolument éviter Londres pour l'Europe et Tokyo/Osaka pour l'Asie. Londres est ainsi fidèle à sa réputation.<br />
<br />
Le PDF est <a href="http://www.mercerhr.com/attachment.dyn?idContent=1129750&filePath=/attachments/English/COL_top50.pdf">disponible ici</a> (98ko).</p>
La panique s'installe
2005-06-22T00:00:00+00:00
2005-06-22T00:00:00+00:00
https://dlecan.com/blog/la-panique-sinstalle/
<p>Suite à mon <a href="https://dlecan.com/blog/peak-oil-atteint/">article sur le <i>peak atteint</i></a> d'il y a quelques semaines, j'avais reçu quelques réactions optimistes : "<i>mais non, ce n'est pas encore la fin du monde, du pétrole y'en a encore pour longtemps</i>". C'était signé G. W. B. !<br />
<br />
Visiblement, tout le monde n'est pas de cet avis, et comme la filière hydrogène est loin d'être opérationnelle, certains tentent de <a href="http://www.futura-sciences.com/news-petrole-tout-prix_6530.php">trouver des solutions</a>.<br />
<br />
Avec un <a href="http://www.reuters.fr/locales/c_newsArticle.jsp?type=businessNews&localeKey=fr_FR&storyID=8853937">pétrole à près de 60 dollars</a>, ces solutions seraient presque rentables ... Attention aux dégâts sur l'environnement toutefois !</p>
Ben tient, justement
2005-06-21T00:00:00+00:00
2005-06-21T00:00:00+00:00
https://dlecan.com/blog/ben-tient-justement/
<p>Je parlais il y a quelques jours du micro financement et justement lundi dernier avait lieu une conférence internationale à Paris sur le micro-financement.<br />
Quelques avis sont divergents, mais globalement tout le monde pense que c'est un bon point de départ pour sortir de la misère.<br />
Voir l'article du <a href="http://www.lematin.ma/economic/article.asp?id=8924">Matin marocain</a>, plutôt optimiste.</p>
Mondialisation ... de la fête !
2005-06-21T00:00:00+00:00
2005-06-21T00:00:00+00:00
https://dlecan.com/blog/mondialisation-de-la-fete/
<p>Je ne pense pas que Jack avait imaginé que sa fête de la musique aurait autant de succès en France, mais aussi dans le monde.<br />
Sur le <a href="http://fetedelamusique.culture.fr/">site dédié à la fête de la musique</a>, j'ai recensé pas moins de 187 villes participant, dans 105 pays différents.<br />
Bien sûr, la plupart du temps il s'agit simplement des français du coin qui font la fête, mais certaines villes se sont réellement imprégnées de l'esprit fête de la musique : Berlin, Bruxelles, Barcelone, Milan Rome, ...<br />
<br />
Un bon exemple de mondialisation de la fête.</p>
Tenter de sortir de la misère
2005-06-17T00:00:00+00:00
2005-06-17T00:00:00+00:00
https://dlecan.com/blog/tenter-de-sortir-de-la-misere/
<p>La pauvreté au niveau mondial se mesure en dollar, au singulier. Ceux qui gagnent moins de 1 dollar par jour sont considérés comme pauvres, les autres non.<br />
<br />
Évidemment, les niveaux de vie ne sont pas équivalent selon les pays, mais on se doute bien qu'un seul dollar n'est pas suffisant pour (sur)vivre, et encore moins pour lancer une activité économique ou commerçante, qui pourrait pourtant permettre de sortir de la misère !<br />
<br />
Évidemment, aucun banque ne prête de l'argent ; les banques ne prêtent de l'argent qu'à ceux qui en ont. Heureusement pour les autres, il existe la solution du micro-crédit qui favorise le développement de nombreuses micro-activités commerciales -principalement pour les femmes- et ainsi tenter de sortir de la misère.<br />
<br />
Exemples de <a href="http://www.missioneco.org/inde/documents_new.asp?V=3_PDF_104300">développement par la microfinance en Inde</a>.</p>
Dis grand-père, c'était comment l'euro ?
2005-06-03T00:00:00+00:00
2005-06-03T00:00:00+00:00
https://dlecan.com/blog/dis-grand-pere-cetait-comment-leuro/
<p>Ainsi pourrait s'exprimer mes petits-enfants dans quelques dizaines d'années si l'on en croit un journal Allemand.<br />
L'euro ne survivrait pas à l'épreuve du temps, ce qui serait bien dommage.<br />
<br />
Les articles de <a href="http://www.liberation.fr/page.php?Article=300757">Libération</a> et du <a href="http://www.lemonde.fr/web/article/0,1-0,36-657309,0.html">Monde</a> à ce propos, mais selon des responsables européens, <a href="http://www.liberation.fr/page.php?Article=301405">"l'euro, c'est pour toujours"</a> (ouf).</p>
Un finish à la "Michel Vaillant"
2005-04-24T00:00:00+00:00
2005-04-24T00:00:00+00:00
https://dlecan.com/blog/un-finish-a-la-michel-vaillant/
<p>Je regarde rarement la Formule 1, surtout depuis la suprématie écrasante de Ferrari sur les autres écuries.<br />
Il semble que les temps changent, puisque l'on assiste depuis le début la saison à la 4è victoire consécutive de Renault, la 3è consécutive d'Alonso et un finish sur ce dernier grand prix digne de la bande dessinée "Michel Vaillant".<br />
<br />
Ce qui m'a toujours déçu dans cette bande dessinée, ce sont les fins de grand prix, chevaleresques et épiques, mais totalement improbable : le finish à la Michel Vaillant.<br />
Il s'agit tout simplement d'un fin de grand prix où s'affrontent deux F1, une Vaillante contre une Leader, une bleue contre une rouge (le bien contre le mal), finissant à quelques mètres l'une de l'autre.<br />
<br />
On ne peut s'empêcher de faire le parallèle avec la fin du grand prix de San-Marin d'aujourd'hui : Alonso (voiture bleue) gagne avec seulement quelques mètres d'avance sur Schumacher (voiture rouge).<br />
<br />
Finalement, comme disent Igor et Grishka, <i>rien n'est impossible</i> ...</p>
Incroyables, ces anglais ! (Gallois, Écossais aussi)
2005-04-16T00:00:00+00:00
2005-04-16T00:00:00+00:00
https://dlecan.com/blog/incroyables-ces-anglais-gallois-ecossais-aussi/
<p>Je reviens d'un petit séjour au Pays de Galles bien sympathique (il faisait beau 😉) qui ne m'a laissé que de bons souvenirs.<br />
<br />
Conduite à gauche évidemment -à laquelle on se fait assez rapidement-, distances exprimées en miles (intéressantes les indications du type "1/4m" pour un quart de mile, ou les "150 yards" dont on ne comprend absolument pas la signification), unités de <a href="http://phys.free.fr/maspoids.htm">masse</a> exprimées en ... grammes !!!<br />
<br />
Voici quelques exemples d'étiquettes vues dans un magasin <a href="http://www.lefigaro.fr/eco-entreprises/20050413.FIG0158.html">Tesco</a> :<br />
<br />
Regardez-les bien, les prix sont indiqués en double affichage kilos/livres ou bien simplement en grammes. Moi qui croyais que le système métrique ne se mettrait jamais en place au Royaume-Unis malgré <a href="http://smdsi.quartier-rural.org/metrologie/systmond.htm">son adoption officielle</a> il y déjà quelques années.<br />
<br />
Évidemment, dans la tête des gens, c'est beaucoup moins clair. Le Royaume-Unis a même obtenu une dérogation permanente auprès de l'Union Européenne pour conserver le mile comme unité de mesure de distance : imaginez la migration de centaines de milliers de panneaux routiers ...<br />
<br />
Enfin, je vous laisser imaginer la complexité des étiquettes quadruple affichage si les anglais passent à l'euro (monnaie/unité de masse) : euro/kg, euro/livre, livre/kg, euro/livre. Sacrées étiquettes sur les marchés !<br />
<br /></p>
"Peak oil" atteint
2005-04-04T00:00:00+00:00
2005-04-04T00:00:00+00:00
https://dlecan.com/blog/peak-oil-atteint/
<p>J'en suis persuadé depuis quelques mois : nous avons atteint le "peak oil".<br />
<br />
Il s'agit pas du moment à partir duquel le pétrole a pas disparu, mais du moment où le prix du pétrole devient élevé durablement (avec une augmentation continue et régulière par la suite).<br />
J'en profite pour vous recommander la lecture de deux dossiers du (feu) magazine <a href="http://www.transfert.net">Transfert</a> : <a href="http://www.transfert.net/d51">l'impasse énergétique</a> et un <a href="http://www.transfert.net/d63">dossier sur l'hydrogène</a>.<br />
<br />
Depuis de longs moins maintenant, le prix du pétrole est élevé (~57 $US à New-York il y quelques jours) et la tendance haussière ne semble pas subir d'essouflement. Il y a bien eu quelques baisses du prix, mais avec de fortes reprises juste après. Et ça n'est <a href="http://www.agefi.ch/Quotidien_en_ligne/News/index.php?newsID=88146">pas près de ralentir</a> !<br />
<br />
Les raisons : production moyenne, consommation très forte (de la chine par exemple). Voir le <a href="http://omrpublic.iea.org/currentissues/full.pdf">rapport de AIE - l'Agence Internationale de l'Energie</a> (PDF). Il est assez intéressant de constater que cette situation intéresse beaucoup de monde tout de même, puisque les companies pétrolières font de <a href="http://np.www.lci.fr/news/economie/0,,3203240-VU5WX0lEIDUy,00.html">larges profits</a> en ce moment.<br />
<br />
Résultat : l'AIE panique -une 3è crise du pétrole serait très mauvaise pour l'économie mondiale- et commence à recommander aux pays de limiter leur consommation de pétrole par <a href="http://www.lemonde.fr/web/article/0,1-0@2-3234,36-634595@51-634665,0.html">diverses mesures</a> : "réduire à 90 km/h la vitesse sur les autoroutes, rendre les transports publics moins chers, voire gratuits, ou encore de promouvoir la circulation alternée".<br />
<br />
Bref, entre ça, la pollution et la mondialisation, notre mode de vie va subir de profonds changements dans les années à venir.</p>
Oui, non ? Finalement, ça n'a pas d'importance
2005-04-03T00:00:00+00:00
2005-04-03T00:00:00+00:00
https://dlecan.com/blog/oui-non-finalement-ca-na-pas-dimportance/
<p>En faisant des <a href="http://www.lemonde.fr/web/article/0,1-0@2-631760,36-633752@51-633875,0.html">calculs savants</a>, on s'aperçoit que voter "oui" ou "non" au référendum sur la Constitution ne changera pas grand chose ...</p>
Un oeil sur le Brésil
2005-03-28T00:00:00+00:00
2005-03-28T00:00:00+00:00
https://dlecan.com/blog/un-oeil-sur-le-bresil/
<p>Ce soir à 22h40 sur France 2, "un oeil sur la planète" spécial Brésil, l'excellente émission de Thierry Thuillier.<br />
<br />
Il est temps de penser au Brésil autrement que pour son football, la samba ou la Caïpirinha. Cinquième pays au monde par sa taille et sa population, le Brésil est aujourd'hui en lutte avec les Etats-Unis pour la place de premier exportateur agricole mondial. C'est aussi l'une des dix premières puissances industrielles de la planète, même s'il déçoit depuis dix ans.<br />
<br />
A ne pas manquer.</p>
Vers une mondialisation plus juste ?
2005-03-18T00:00:00+00:00
2005-03-18T00:00:00+00:00
https://dlecan.com/blog/vers-une-mondialisation-plus-juste/
<p>Le Conseil Economique et Social a publié il y a quelques semaines un <a href="http://www.ces.fr/rapport/doclon/05022802.pdf">rapport </a>dans lequel plusieurs pistes de réflexion pour une mondialisation plus juste sont explorées.<br />
<br />
Intéressant si on pense que c'est possible et qu'on y croit.</p>
Padanie et autre Transdniestrie
2005-03-12T00:00:00+00:00
2005-03-12T00:00:00+00:00
https://dlecan.com/blog/padanie-et-autre-transdniestrie/
<p><img src="http://www.courrierinternational.fr/evenement/hors-serie/01-2005/images/couv2005-1.gif" alt="L'atlas des atlas" align="left"/><a href="http://www.courrierinternational.fr">Courrier International</a> vient de sortir un numéro spécial : "<a href="http://www.courrierinternational.fr/evenement/hors-serie/01-2005/edito.asp">L'atlas des atlas</a>".<br />
<br />
Consacré à la présentation de la géographie mondiale, il montre principalement la façon dont chaque pays voit notre monde. Et de part et d'autre d'une frontière, les interprétations et les opinions peuvent largement différer !<br />
<br />
Il coûte 12€ et les vaut largement.</p>
La place du nationalisme à l'heure de l'Europe
2005-02-24T00:00:00+00:00
2005-02-24T00:00:00+00:00
https://dlecan.com/blog/la-place-du-nationalisme-a-lheure-de-leurope/
<p>Ca date de quelques semaines déjà, mais je trouve que la situation entre Flamands et Wallons s'aggrave d'années en années.<br />
<br />
Comme le rapporte <a href="http://www.lemonde.fr/web/article/0,1-0@2-3214,36-394653,0.html">Le Monde</a>, les Flamands cherchent à rendre les deux parties de la nation belge de plus en plus indépendantes l'une de l'autre.<br />
Forcément, ça coince au niveau de la ville de Bruxelles, enclave francophone dans la partie flamande du pays.<br />
<br />
Alors qu'on cherche à rapprocher des peuples et des pays en construisant l'Europe, est-ce qu'il y a de la place pour l'éclatement d'un d'entre eux ? <br />
<br />
Update : ça coince pas mal aussi en <a href="http://www.lefigaro.fr/eco-monde/20050224.FIG0012.html">Espagne</a> ...</p>
Réflexion sur mon objectivité
2005-02-19T00:00:00+00:00
2005-02-19T00:00:00+00:00
https://dlecan.com/blog/reflexion-sur-mon-objectivite/
<p>C'est intéressant de voir comment chaque personne qui écrit un blog rencontre à un moment où à un autre les mêmes situations.<br />
<br />
Parmi la cinquantaine de weblogs que je suis, tous ont plus ou moins écrit un billet à propos des remarques que leur entourage (famille, collègues, ...) pouvait leur faire et des conséquences que cela pouvait avoir.<br />
On embraye alors sur des sujets comme "<i>est-ce que je peux vraiment écrire ce que je pense de mon boulot si mon boss me lit</i>" ou bien "<i>j'ai dis que mon voisin est un connard, mais pas de bol il a Internet</i>".<br />
<br />
Rançon du succès. Et il ne faudrait pas se plaindre, on écrit pour être lu quand même !<br />
<br />
Bref, j'en viens à ma situation. On m'a fait des remarques sur mon objectivité. Première confrontation physique avec un lecteur. Mince, moi pensait (naïvement ?) écrire de manière neutre, c'est un peu loupé. Je décide de creuser un peu, pour comprendre ce qui lui fait dire ça. Il me parle d'impression générale, pas d'élément en particulier.<br />
Je suis complètement à côté de la plaque : on ne peut pas être objectif ...<br />
<br />
Concrètement, il m'a surtout reproché mes sources journalistiques. C'est vrai qu'elles proviennent principalement du <a href="http://www.lemonde.fr">Monde</a> et de <a href="http://www.liberation.fr">Libération</a> et apparemment, l'origine de ces sources jouent beaucoup contre mon objectivité car elles ne sont pas assez variées.<br />
<br />
Effectivement, je ne poste pas de références du <a href="http://www.lepoint.fr">Point</a> ou du <a href="http://www.lefigaro.fr">Figaro</a>, mais je ne n'ai pas non plus venant de l'<a href="http://www.lexpress.fr">Express</a> par exemple.<br />
<br />
L'explication est simple. Pour Le Monde, j'y suis abonné, donc facile pour moi d'y faire référence. Pour Libération, ils ont cet avantage de fournir un fil d'actualité RSS : l'information vient à moi. Les autres n'en fournissent pas à ma connaissance et je n'ai pas le temps malheureusement d'aller visiter tous les sites tous les jours.<br />
<br />
Cela nuit à mon objectivité, je vais faire des efforts 😄.</p>
La puissance se mesure aussi à ça !
2005-02-16T00:00:00+00:00
2005-02-16T00:00:00+00:00
https://dlecan.com/blog/la-puissance-se-mesure-aussi-a-ca/
<p>La Chine possède(ra) autant d'abonnés au téléphone mobile que dans l'Europe tout entière.<br />
<br />
Les chiffres de <a href="http://www.neteconomie.com/perl/navig.pl/neteconomie/infos/article/20050114181833">NetEconomie</a> sont affolants : environ 345 millions d'abonnés au téléphone mobile en 2004 et 400 millions attendus fin 2005.<br />
<br />
A comparer aux <a href="http://www.journaldunet.com/cc/05_mobile/mobile_marche_eu.shtml">284 millions d'abonnés en Europe</a> en 2002 (estimé à 330 millions en 2005) ...</p>
L'heure des bilans
2005-02-12T00:00:00+00:00
2005-02-12T00:00:00+00:00
https://dlecan.com/blog/lheure-des-bilans/
<p>Davos et Porto Alegre, c'est terminé pour cette année.<br />
<br />
Quelques articles à lire : <a href="http://www.liberation.fr/page.php?Article=272230">Libé 1</a>, <a href="http://www.liberation.fr/page.php?Article=272049">Libé 2</a> et enfin pour se marrer : <a href="http://www.liberation.fr/page.php?Article=272819">Libé 3</a>.<br />
Bref, pas autant de retentissement que les années passées ...<br />
<br />
Histoire de changer, la Chine a beacoup <a href="http://www.lemonde.fr/web/article/0,1-0@2-3210,36-396168,0.html">fait parler d'elle</a> à Davos. Voici <a href="http://celine-en-chine.over-blog.com/trackback.php?Id=85056">un billet</a> qui l'illustre, dans un blog qui m'a l'air très prometteur et plein d'infos sur la Chine et Shanghaï (on a les mêmes références visiblement).</p>
L'année des ratifications
2005-02-06T00:00:00+00:00
2005-02-06T00:00:00+00:00
https://dlecan.com/blog/lannee-des-ratifications/
<p>2005 est LA grande année pour la nouvelle Constitution européenne.<br />
<br />
Déjà ratifiée par la Lituanie et la Hongrie, la Constitution le sera soit par référendum (consultatif ou non), soit par voie parlementaire pour les autres pays.<br />
<br />
Référendums : Danemark, Espagne en février (consultatif), Irlande, Luxembourg (consultatif), Pays-Bas (consultatif), Pologne, Portugal, République tchèque, Royaume-Uni (consultatif) et France.<br />
<br />
Une question se pose assez souvent quand on évoque la Constitution : que ce passera-t-il si un ou plusieurs pays la rejettent ?<br />
<br />
J'ai trouvé un élément de réponse dans <a href="http://www.lemonde.fr/">Le Monde</a> du 07 janvier 2005, dans une interview de <b>Inigo Mendez de Vigo</b>, député européen espagnol, corapporteur du projet de Constitution européenne.<br />
<br />
Pendant l'entretien, il évoque "<i>une déclaration annexée à la Constitution </i>[qui]<i> prévoit que, si seuls les quatre cinquièmes des États ont ratifié le traité dans un délai de deux ans, le Conseil européen se saisit de la question. Cela signifie que, si leur masse critique est suffisante, les États qui auront ratifié le traité iront de l'avant. Ils dénonceront les traités existants et se réuniront le lendemain pour approuver la nouvelle Constitution. Ceux qui pensent que rien ne se passera en cas d'échec se trompent. Nous avons trop investi dans cette Constitution pour accepter son échec.</i>" Si quelqu'un trouve une référence vers cette annexe, merci de me la transmettre.<br />
<br />
Nous aurions alors une nouvelle Europe : celle des pays qui ont accepté la nouvelle Constitution ; nouvelle Europe qui s'ajoutera aux autres : zone Euro, espace de Schengen, ...<br />
<br />
<u>Update</u> : Le peuple belge <a href="http://www.euractiv.com/Article?tcmuri=tcm:28-134603-16&type=News">ne votera pas</a>.</p>
En plein dedans
2005-01-27T00:00:00+00:00
2005-01-27T00:00:00+00:00
https://dlecan.com/blog/en-plein-dedans/
<p>On est en plein dedans mais certains plus que d'autres.<br />
<br />
<a href="http://www.lemonde.fr">Le Monde</a> propose de suivre le <a href="http://davos.blog.lemonde.fr/">sommet de Davos</a> et le <a href="http://portoalegre.blog.lemonde.fr/">forum social mondial de Porto Alegre</a> dans deux blogs.<br />
A suivre ...</p>
La Chine plus très loin de la 5è place
2005-01-22T00:00:00+00:00
2005-01-22T00:00:00+00:00
https://dlecan.com/blog/la-chine-plus-tres-loin-de-la-5e-place/
<p>En cherchant à connaître de manière chiffrée brute la puissance de la Chine d'aujourd'hui, j'ai eu quelques suprises sur ce pays, mais aussi sur la France.<br />
<br />
Autant que je me souvienne, j'ai toujours entendu que la France était la <strong>quatrième puissance mondiale</strong>. Les chiffres me déçoivent !<br />
<br />
La <a href="http://www.banquemondiale.org/EXT/French.nsf/DocByUnid/34A9F43D563CEA2085256D71006AE08F?Opendocument">Banque Mondiale</a> (j'ai rarement vu des liens aussi mal nommés) fournit tous les chiffres dont j'ai eu besoin, avec un historique de cinq ans.<br />
<br />
Commençons par <a href="http://www.worldbank.org/data/databytopic/GNI.pdf">le classement des pays par RNB</a> en 2003 (PDF de 22ko). Pour information, le <em>Revenu National Brut</em> est l'ancien PNB, <em>Produit National Brut</em>. Pour les anglophones, il s'agit du GNI (<em>Gross National Income</em> ou anciennement GNP, <em>Gross National Product</em>.<br /></p>
<ul>
<li>Première surprise : la France n'est pas la quatrième puissance mondiale, mais la cinquième, le Royaume-Unis occupant cette place.<br /></li>
<li>Deuxième surprise : la Chine qui nous talonne de près !!<br />
<br />
Quelque peu étonné de ces données, je décide de chercher quand ce retournement de position a eu lieu. Cette fois-ci j'ai utilisé les possibilités de <a href="http://devdata.worldbank.org/data-query/">cherche par critère économique/pays/années</a> du site de la Banque Mondiale pour trouver ce que je voulais.<br />
Et voici que l'on obtient :<br />
<img src="http://www.dlecan.com/uploads/gni-france-uk-chine.png" alt="GNI comparé France UK Chine" /><br />
Grosse déprime de l'économie française au début des années 2000.<br />
<br />
Effectivement, nous avons perdu notre quatrième place en 2000, et nous ne tarderons pas à céder notre place actuelle à la Chine. Même si la France a redressé la barre en 2003, l'économie chinoise ne tardera pas à nous rattraper, portée par des taux de croissance hallucinants.<br />
<br />
Mais cette lame de fond inéluctable rattrapera aussi les autres pays, les uns après les autres. Voilà pourquoi il ne faut plus sous-estimer la Chine, <b>la</b> puissance de demain. Les américains n'ont qu'à bien se tenir, ce n'est qu'une question de temps.</li>
</ul>
L'Allemagne durcit le ton
2005-01-19T00:00:00+00:00
2005-01-19T00:00:00+00:00
https://dlecan.com/blog/lallemagne-durcit-le-ton/
<p>Pas cool les allemands !<br />
Pris à la gorge par un énorme taux de chômage et des réformes impopulaires (obligatoires), Schröder n'a pas d'autres choix que de demander une modification des critères du Pacte de Stabilité, à l'opposé de ce que l'Allemagne pronait il y a 10 ans.<br />
<br />
L'<a href="http://www.lemonde.fr/web/article/0,1-0@2-3214,36-394650,0.html">article</a> du Monde d'aujourd'hui dresse un tableau assez inquiétant des ambitions de l'Allemagne à moyen terme mais montre bien que Schröder veut aller de l'avant (et tant pis pour ses partenaires).<br />
<br />
Je déteste particulièrement le passage "<i>[L'Allemagne trouve que] la Banque centrale européenne [...] mène une politique adaptée à l'ensemble de la zone [...] trop dure pour l'Allemagne, qui ne connaît pas d'inflation.</i>". C'était le jeu du passage à la monnaie unique : les mêmes règles pour tout le monde.</p>
Tout ce que vous avez toujours voulu savoir sur l'OMC
2005-01-19T00:00:00+00:00
2005-01-19T00:00:00+00:00
https://dlecan.com/blog/tout-ce-que-vous-avez-toujours-voulu-savoir-sur-lomc/
<p><img src="http://www.wto.org/images/img_logos/10anniv_160px.gif" alt="Logo OMC" /><br />
2005 marque le dixième anniversaire de l'OMC.<br />
<br />
A cette occasion, une partie du site de l'organisation est <a href="http://www.wto.org/french/thewto_f/10anniv_f/10anniv_f.htm">spécialement dédiée</a> à cet anniversaire. Intéressant.<br />
<br />
Pour rappel, le but de l'OMC "<i>est d'aider, par la réduction d'obstacles au libre échange, les producteurs de marchandises et de services, les exportateurs et les importateurs à mener leurs activités</i>" (citation <a href="http://fr.wikipedia.org/wiki/OMC">Wikipedia</a>).<br />
<br />
Pour information, l'OMC se décrit de cette <a href="http://www.wto.org/french/thewto_f/whatis_f/whatis_f.htm">manière</a>. D'autres descriptions sont moins favorables, comme celle du <a href="http://www.monde-diplomatique.fr/dossiers/omc/">Monde Diplomatique</a>. Il y en a bien d'autres, dans tous les domaines (agriculture, environnement, emploi, ...).</p>
Les pays de l'Est ne sont plus
2005-01-16T00:00:00+00:00
2005-01-16T00:00:00+00:00
https://dlecan.com/blog/les-pays-de-lest-ne-sont-plus/
<p>... et il n'y a pas qu'eux !<br />
<br />
Alors que dans nos esprits d'occidentaux les ex-pays de l'Est, un certain nombre de pays d'Asie et d'Amérique du Sud paraissent encore comme des pays "arriérés", la réalité est tout autre.<br />
<br />
Leurs habitants le disent eux-même. Il suffit qu'ils quittent quelques années leur pays pour, au retour, contater les énormes changements en cours.<br />
La Roumanie, la Bulgarie sont sur la liste des prétendants à l'entrée dans l'Union européenne. Ils ont (presque) le niveau de développement suffisant. Bien sûr, de nombreux autres changements devront encore avoir lieu, mais l'essentiel est déjà fait : ils ont la motivation.<br />
<br />
Pourtant, je ne donne pas cher de l'image qu'ont les français par exemple à propos du Portugal ou de la Grèce, vingt années après leur intégration. Les préjugés persistent, durent, alors que les efforts et les changements sont réels.<br />
<br />
Donnons-leur une chance de nous rejoindre : eux aussi ont le droit de consommer, de s'acheter trois télés et de faire les soldes deux fois par an (sic !).<br />
Je pense que c'est valable aussi pour la Turquie. A lire l'excellent dossier de l'<a href="http://www.lexpress.fr/info/monde/dossier/ue/dossier.asp?id=506695">Express</a> à ce propos.</p>
Duel sur les clous #2
2005-01-12T00:00:00+00:00
2005-01-12T00:00:00+00:00
https://dlecan.com/blog/duel-sur-les-clous-2/
<p>J'ai passé quelque temps en Allemagne il y a quelques années et je crois bien que c'était le paradis des passages pour piétons.<br />
Là où en France il faut nager au milieu des crocodiles, le passage pour piétons est un gué sûr, fiable et serein en Allemagne.<br />
<br />
Quel plaisir de traverser la route sans avoir à forcer le passage ! Les voitures s'arrêtent -prévenantes- au moindre signe que l'on peut faire en direction d'un passage clouté, même sans franchissement.<br />
<br />
La traversée de la route est un dû pour les piétons ... du moyen qu'ils tentent de traverser dans les clous et surtout pas en dehors. Là par contre, on est plutôt la cible à abattre, chassée par les voitures mais aussi par les autres piétons ! Les règles sont simples : on ne traverse qu'aux passages prévus, mais rien ne doit entraver ou retarder le franchissement de la route. Pour moi, ce serait la liberté, la fin de la prise de risque quand je vais au travail le matin. Joie.<br />
<br />
Récemment en vacances en Suède, je m'attendais un peu à retrouver cette rigueur germanique faite de règles que personne ne pense à enfreindre.<br />
Et bien pas du tout, les suédois se comportent comme les latins : traverser n'importe où, n'importe comment et se battre pour traverser, même dans les "clous". Je m'y suis senti comme chez moi.<br />
<br />
Il paraît qu'en Angleterre, ça se passe un peu comme en Allemagne. Il faudra que je vérifie ça un jour.</p>
Liberté d'expression contrôlée
2005-01-08T00:00:00+00:00
2005-01-08T00:00:00+00:00
https://dlecan.com/blog/liberte-dexpression-controlee/
<p>Plus j'étends ma lecture des blogs, plus je me rend compte des difficultés que cela représente.<br />
<br />
<b>Il faut tenir la route.</b><br />
Pour certain, la lassitude l'emporte ou le sujet traité s'épuise ou n'est pas assez actif. <a href=" http://www.cybercodeur.net/weblog/commentaires/detailsCarnet.php?idmessage=1108">Denis Boudreau</a> débutait mal l'année 2005, mais semble s'être repris depuis.<br />
<br />
<b>Il faut contrôler attentivement ce qui est écrit.</b><br />
Ceci est mon site personnel par définition : le nom de domaine du site est mon nom de famille et j'y ai mis mon CV. Des recruteurs y passent quelquefois, quelquefois lisent aussi mes billets. Par conséquent, je ne peux pas y écrire n'importe quoi. <a href="http://www.svay.com/blog/index/2005/01/07/225-blogguer-ici-blogguer-ailleurs">Maurice Svay</a> l'a bien compris, puisqu'il pense bloguer autre part pour des sujets plus personnels (peut-être plus dérangeant).<br />
<br />
Donner ces opinons, faire avancer le <i>schimlblick</i> sont les buts d'un blog. Mais la censure est obligatoire. Ecrire autre part, anonymement de plus, c'est ne plus avoir de limite ou de censure, ainsi qu'admettre et accepter que l'on a des idées qui peuvent nous desservir.<br />
<br />
En parlant de mondialisation, je prend le risque de passer pour un "pro" ou un "anti", ce qui n'est pas mon but. En espérant que mes lecteurs sauront me replacer dans le bon le chemin.</p>
Duel sur les clous #1
2005-01-06T00:00:00+00:00
2005-01-06T00:00:00+00:00
https://dlecan.com/blog/duel-sur-les-clous-1/
<p>Chaque matin, je dois me battre pour traverser une bande d'asphalte d'à peine trois voies. Elle est juste à côté de chez moi et malheureusement assez passagère.<br />
Selon les jours et mon humeur, deux techniques se présentent :<br /></p>
<ul>
<li>la technique <i>je-force-le-passage-car-je-suis-en-forme</i><br /></li>
<li>la technique <i>je-me-fais-entuber</i><br />
<br />
<b><i>je-force-le-passage-car-je-suis-en-forme</i></b><br />
C'est à ces moments là que se produisent de vrais duels, entre le piéton et la voiture. Il faut les voir ces bolides qui accélèrent comme des malades parce qu'ils pensent qu'ils peuvent avoir le prochain feu au vert ... pour gagner 3 minutes. Mais ce n'est pas le débat.<br />
Cette rue ressemble un peu à ces rivières d'Afrique où les crocodiles attendent patiemment que les gnous se jettent à l'eau. Et moi je tente de nager au milieu des voitures.<br />
<br />
Les jours où je suis en forme, je provoque les voitures en duel. Je cherche le regard des conducteurs (pas facile, il y a trois voies), et quand ils m'ont vu je sais instantanément si je vais pouvoir traverser.<br />
Quelquefois ça marche, une voiture s'arrête, puis deux. Mais attention il reste encore la troisième voie. C'est le moment le plus dangereux, car une voiture peut débouler sur cette 3è voie, exaspérée par l'arrêt des voitures sur les autres voies et le feu qui va passer au rouge un peu plus loin.<br />
Pour le moment, je m'en suis toujours sorti vivant. A la différence des gnous qui sont en troupeau et traversent une fois par an, je suis seul sur le passage et je traverse tous les jours.<br />
<br />
Quelquefois aussi ça ne marche pas.<br />
<br />
<b><i>je-me-fais-entuber</i></b><br />
Ca, c'est pour les jours de déprime, de pluie, de fatigue ou quand je capte pas le regard des conducteurs. J'attend, j'attend. Il faut attendre que la route se libère, trouver la bonne configuration de voitures qui va me permettre de traverser sans encombres. Je cours aussi.<br />
La journée commence mal.<br />
<br />
<b>La législation</b><br />
L'article <a href="http://www.legifrance.gouv.fr/WAspad/UnArticleDeCode?code=CROUTENR.rcv&art=R415-11">R415-11 du code de la route</a> stipule que "<i> Tout conducteur est tenu de céder le passage aux piétons régulièrement engagés dans la traversée d'une chaussée.</i>"<br />
Voilà, c'est simple, si on est pas engagé sur la route, les voitures ne sont pas tenues de s'arrêter.<br />
J'ai un peu voyagé, et certains pays ont des comportements beaucoup plus civilisés (j'y reviendrai). Mais à la lecture de la loi, tant que je reste sur le trottoir, les voitures ne semblent pas être tenues de s'arrêter. Grrr...<br />
<br />
<b>Remarque</b> :<br />
Il m'a fallu une demi-heure pour construire le lien vers l'article du code de la route. Après avoir vainement tenter de copier-coller le lien que j'obtenais en cherchant le fameux article R415-11 du code de la route (je n'obtenais que des erreurs de session qui n'existe pas), je suis tombé sur un tout petit lien en bas de la <a href="http://www.legifrance.gouv.fr/html/index.html">page d'accueil</a>. Pour une obscure raison, il faut construire le lien à la main, selon des règles <a href="http://www.legifrance.gouv.fr/html/liens/etablir_lien.htm">assez complexes</a>. Regardez le paragraphe 3 ...</li>
</ul>
La course aux chiffres
2005-01-05T00:00:00+00:00
2005-01-05T00:00:00+00:00
https://dlecan.com/blog/la-course-aux-chiffres/
<p>J'ai entendu hier soir à la radio que l'Allemagne avait annoncé avoir débloqué 1/2 millard d'euros sur deux ans pour aider les victimes du tsunami en Asie du sud-est. C'est à celui qui donnera le plus.<br />
<br />
L'intention est très louable mais j'ai tout de même du mal à croire et à comprendre ce gigantesque élan de solidarité qui court depuis quasiment dix jours.<br />
<br />
Le phénomène de modialisation se caractérise principalement par ses impacts au niveau économique :<br /></p>
<ul>
<li>délocalisations<br /></li>
<li>déréglementations<br /></li>
<li>accroissement en général des richesses des pays en voie de développement<br /></li>
<li>tourisme partout, tout le temps, par de plus en de gens<br />
<br />
Mais cette fois-ci, c'est un nouveau type d'échange qui se met en place. Au début, les pays riches, mais aussi certains pays qui ont donné selon leurs moyens (le symbole est très fort je trouve), ont donné des aides d'urgence.<br />
La phase deux démarre aujourd'hui, avec cette réunion entre de nombreux chefs d'états, têtes politiques connues et d'instutions mondiales. Il s'agit d'utiliser correctement l'argent récolté en pérennisant la reconstruction des pays dévastés et ne laissant pas leurs habitants vivre sans maison ou sans infrastructures après avoir échappé à la mort.<br />
Une mondialisation de la solidarité en quelque sorte.<br />
<br />
Personnellement, j'ai un peu l'impression d'assister à la mise en place par les pays riches d'une sorte de <a href="http://www.seminaire-sherbrooke.qc.ca/hist/hist5/travaux/gf/gf4.htm">plan Marshall</a>. On verra à l'avenir si cette solidarité peut se reproduire, et surtout si elle est sincère.</li>
</ul>
Un domaine de plus acquis à la Chine
2005-01-03T00:00:00+00:00
2005-01-03T00:00:00+00:00
https://dlecan.com/blog/un-domaine-de-plus-acquis-a-la-chine/
<p>L'info est passée presque inaperçue, pourtant elle va avoir un impact énorme sur le marché du textile mondial. <a href="http://www.liberation.fr/page.php?Article=265126">Libération</a> rapporte la mise en application de la dérégulation totale du marché du textile au niveau mondial.<br />
<br />
Si on ne parle déjà plus de ce type de produits manufacturés dans nos pays dits "du nord", ils font vivre quantité de personnes dans divers pays "du sud".<br />
<br />
Le passage le plus intéressant de l'article concerne les impacts sociaux qu'impose la domination de la Chine : <i>"la Chine tire les standards sociaux vers le bas"</i>.<br />
Alors qu'habituellement, le développement économique d'un pays s'accompagne d'une progression des droits sociaux des habitants, cette fois-ci, elle les tire vers le bas à cause de la concurrence. Quand on sait de plus que les bas prix de la main d'oeuvre sont aussi le fait du <a href="http://www.droitsenfant.com/asie.htm">travail des enfants</a>, on ne peut que s'inquiéter ...<br />
<br />
Voir aussi les articles complémentaires de <a href="http://www.lemonde.fr/web/recherche_articleweb/1,13-0,36-392233,0.html">Le Monde</a> et de <a href="http://www.liberation.fr/page.php?Article=265653">Libération</a>.</p>
Les sujets abordés
2005-01-02T00:00:00+00:00
2005-01-02T00:00:00+00:00
https://dlecan.com/blog/les-sujets-abordes/
<p>Les limites de ce blog ne sont pas encore clairement fixées. Des tas de sujets sont déjà dissertés, dissequés, analysés dans un autre tas de blogs, de forums et de newsgroup et il n'est pas facile de se faire une place.<br />
<br />
Les blogs sont souvent la place de témoignage <i>sincères</i>, de la part de blogueurs qui vivent l'actualité. Je vous renvoie vers tous les sites qui parlent du tsunami catastrophique qui a frappé l'asie du sud-est (en particulier <a href="http://fr.wikipedia.org/wiki/Tremblement_de_terre_du_26_d%C3%A9cembre_2004">Wikipedia</a>)<br />
Personnellement, je ne suis pas au centre de l'actualité, mais un mouvement aussi puissant que ce tsunami est en cours m'intéresse : la <b>mondialisation</b>.<br />
Je n'entend pas en parler de manière polémique, la mondialisation ayant des aspects positifs et négatifs. Dans tous les cas, je considère qu'il n'y pas que <i>nous</i> qui avons droit à la richesse.<br />
<br />
L'Europe sera aussi un des sujets de discussions de ce blog, surtout cette année avec les tentatives de ratification de la <a href="http://www.vie-publique.fr/actualite/dossier/constitution_europeenne/constitution_europeenne.htm">Constitution européenne</a> de plusieurs grands pays.<br />
<br />
Les différences culturelles entre pays est un autre sujet qui me passionne. Ce sont les petit détails qui comptent : style de vie, alimentation, travail, en dehors bien sûr des clichés habituels que l'on a sur un pays.<br />
<br />
Enfin, une chose est sûre par contre : je vais tout faire pour éviter de parler d'informatique, même si l'envie ne manque pas ! Je ferai toutefois exception pour <a href="http://babydog.free.fr/">Babydog</a>, le logiciel que j'ai créé avec une vétérinaire. Je vous laisse consulter le site dédié de <a href="http://babydog.free.fr/">Babydog</a> si vous voulez plus d'informations.</p>
Ca y est, ça commence !
2005-01-01T00:00:00+00:00
2005-01-01T00:00:00+00:00
https://dlecan.com/blog/ca-y-est-ca-commence/
<p>C'est symbolique, mais cette nouvelle année pour moi signifie beaucoup de choses :<br /></p>
<ul><li>Je refonds entièrement mon site avec l'introduction d'un weblog sur les grand pays de ce monde et leurs interactions avec les autres (mondialisation)</li><li>Je met à jour mon CV (ça faisait un an que je n'y avais pas touché)</li><li>Je ne parle pas, enfin pas trop, d'informatique dans ce blog</li><li>Si j'ai le temps, j'ouvre une crèperie en Chine. Je suis sûr qu'il y a des clients !</li></ul>Acteur passif depuis de long mois, j'ai décidé de franchir le pas ce 1er janvier 2005 et de tenter ma chance.<br />
Certains "bloguent" depuis des années, pour moi, l'exercise est nouveau. Mais Il paraît que 2005 sera l'année des blogs, alors il faut que j'essaie.<br />
<br />
Rendez-vous le <b>1er janvier 2006</b> pour faire le bilan de cette première année.