The git repo behind my blog.

rss.xml 135KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  3. <channel> <atom:link href="http://phyks.me/rss.xml" rel="self" type="application/rss+xml"/>
  4. <title>Phyks' blog</title>
  5. <link>http://phyks.me</link>
  6. <description>Phyks' blog</description>
  7. <language>fr</language>
  8. <copyright>CC BY</copyright>
  9. <webMaster>webmaster@phyks.me (Phyks)</webMaster>
  10. <lastBuildDate>Wed, 31 Dec 2014 23:38:53 -0000</lastBuildDate>
  11. <item>
  12. <title>Getting ipv6 to work with a Kimsufi server</title>
  13. <link>http://phyks.me/2014/11/ipv6_kimsufi.html</link>
  14. <guid isPermaLink="true">http://phyks.me/2014/11/ipv6_kimsufi.html</guid>
  15. <description>Starting from yesterday, my server (phyks.me) should be available using ipv6. This was not the case before due to laziness and a lack of configuratio…</description>
  16. <content:encoded><![CDATA[<div class="article">
  17. <header></header>
  18. <!--
  19. @author=Phyks
  20. @date=09112014-1945
  21. @title=Getting ipv6 to work with a Kimsufi server
  22. @tags=Phyks
  23. -->
  24. <p>Starting from yesterday, my server (<a href="http://phyks.me">phyks.me</a>) should be available using ipv6. This was not the case before due to laziness and a lack of configuration. However, as setting ipv6 on a Kimsufi seems to not be really straight-forward (out of date documentation, information disseminated over the web and difficult to find between basic mistakes and real errors…), I think it may be useful to keep some notes here. Hope it can help anyone.</p>
  25. <p>The <a href="http://help.ovh.co.uk/Ipv4Ipv6">doc</a> explains that OVH has not set ipv6 autoconfig on their servers, and that you should configure the default route and IP address yourself.</p>
  26. <p>To find your ip address, it is pretty easy: just go to your manager and look for the ipv6 address in the IP section.</p>
  27. <p><code>ip -6 addr add YOUR_IPV6_ADDRESS/64 dev eth0</code></p>
  28. <p>This will add the ipv6 address to your network device. Then, you have to manually add the default gateway. To get its address, you should remove the last two digits of your ipv6 address and put <code>FF:FF:FF:FF:FF</code> instead. This means that <code>2001:41d0:1:4462::1/64</code> will give you a default gateway <code>2001:41d0:1:44FF:FF:FF:FF:FF</code>.</p>
  29. <p>Then, you should add a default route <em>via</em> this gateway</p>
  30. <p><code>ip -6 r a default via 2001:41d0:1:44FF:FF:FF:FF:FF</code></p>
  31. <p>This is the standard procedure explained in OVH guide and many posts around the web such as <a href="https://www.skyminds.net/serveur-dedie-mise-en-place-de-lipv6/">this one</a> (in French). It may work in some cases, however, in my case, I could not reach the default gateway and then, I could not add this route.</p>
  32. <p>I found <a href="http://forum.ovh.co.uk/showthread.php?6435-Getting-IPv6-working-on-kimsufi&amp;p=44965&amp;viewfull=1#post44965">a comment</a> on the OVH forum giving a solution.</p>
  33. <p>You should first add a route to reach the gateway</p>
  34. <p><code>ip -6 r a 2001:41d0:1:44FF:FF:FF:FF:FF dev eth0</code></p>
  35. <p>and then, you can add the default route <em>via</em> this gateway</p>
  36. <p><code>ip -6 r a default via 2001:41d0:1:44FF:FF:FF:FF:FF</code></p>
  37. <footer>
  38. <p class="tags">Tags : <a href="http://phyks.me/tags/Phyks.html">Phyks</a></p></footer>
  39. </div>]]></content:encoded>
  40. <pubDate>Sun, 09 Nov 2014 17:45:00 -0000</pubDate>
  41. <category>Phyks</category>
  42. <author>webmaster@phyks.me (Phyks)</author>
  43. </item>
  44. <item>
  45. <title>Proof-of-concept: BloomySearch, a (JavaScript) client-side search engine for static websites</title>
  46. <link>http://phyks.me/2014/11/bloomysearch.html</link>
  47. <guid isPermaLink="true">http://phyks.me/2014/11/bloomysearch.html</guid>
  48. <description>Overview
  49. Many websites and blogs are statically generated and the webserver only serves static file…</description>
  50. <content:encoded><![CDATA[<div class="article">
  51. <header></header>
  52. <!--
  53. @author=Phyks
  54. @date=08112014-1845
  55. @title=Proof-of-concept: BloomySearch, a (JavaScript) client-side search engine for static websites
  56. @tags=Dev, Web
  57. -->
  58. <h2>Overview</h2>
  59. <p>Many websites and blogs are statically generated and the webserver only serves static files. It is the case of many doc websites and more and more blogs, starting from this one, as <a href="http://jekyllrb.com/">Jekyll</a> / <a href="http://blog.getpelican.com/">Pelican</a> develops.</p>
  60. <p>This is really useful to reduce the complexity of the website and the load on the webserver. All the complex logic is done at the generation.</p>
  61. <p>However, this also means you do not have dynamic pages on your website to handle search queries. Then, you are left with two (or three) choices :</p>
  62. <ol>
  63. <li>Use an external search engine, such as an embedded Google search box. This raises some privacy concerns and make you depends on an external service. </li>
  64. <li>(Use a JS search engine such as the <a href="http://www.airpair.com/angularjs#/10-filters-core-">filters</a> provided by Angular.JS. This only works on the displayed content, and is not a real solution). </li>
  65. <li>Stop worrying about search engine on your website and let the users <code>wget</code>-ing and <code>grep</code>-ing your website on their computers. This is not the most user-friendly solution…</li>
  66. </ol>
  67. <p>There are a couple of solutions around, mostly based on <a href="http://lunrjs.com/">Lunr.js</a> which generates an index from the articles available, and use this index for fulltext search. This is the best solution I found so far but it is still not perfect. Although there is a stemmer and an index generation to reduce the amount of data to be transferred, the data is not stored in a very efficient way, and the full index is sent as JSON. An example implementation for Jekyll is available through <a href="https://github.com/slashdotdash/jekyll-lunr-js-search">the jekyll-lunr-js-search plugin</a>.</p>
  68. <p>I had the idea of a client side search engine in mind for a while, but was facing the same problem as Lunr.js: how not to send a full (very large) index over the network to every single client ? Not having an optimized data structure would basically mean sending twice the content of the website to the client. It may not be a practical problem nowadays, as transfer speed is not always the limiting resource, but it is still not to be considered as a good practice, in my opinion, especially if your website might be accessed from mobile devices.</p>
  69. <p>I came accross <a href="http://www.stavros.io/posts/bloom-filter-search-engine/?print">this article</a> from Stavros Korokithakis and thought something similar could be achieved directly in the browser. Instead of using a standard dictionary to store the index, this article proposes to use a Bloom filter per article. Bloom filters are very interesting probabilistic structures which can store whether an element is or not in a set, with a fixed number of bits. It can return false positives: if an element is in the set, it always returns <code>True</code>, but if an element is not in the set, it may say it is actually in, with a small probability. <a href="https://en.wikipedia.org/wiki/Bloom_filter">Wikipedia page</a> on the subject has all the necessary stuff to understand these data structures.</p>
  70. <p>I wrote it in the context of my blog, which means a Python script to generate the index at pages generation, and a client side search engine in JavaScript, running in browser.</p>
  71. <p>A demo is available <a href="https://phyks.github.io/BloomySearch/">here</a>. It contains all the articles of my blog, as of writing this article, totalizing 160k characters, and only 7kB of index, allowing 10% of false positives, which may be a bit too much for a really reliable search engine. Reducing the error rate will lead to an increase in the index size (11kB for 1% of false positives and the same amount of characters).</p>
  72. <h2>Details of the implementation</h2>
  73. <p>As JavaScript is not the easier language to use for hashing and binary data manipulation, I started by implementing the client side search engine. Then, it would be easier to adapt the Python code to the JS lib than doing the contrary. Actually, I found <a href="https://github.com/jasondavies/bloomfilter.js">this bloomfilters.js library</a> from Jason Davies which was doing most of the job and did not need many modifications. I edited it a bit to support a construction with a <code>capacity</code> and an <code>error_rate</code>, instead of an explicit number of bits and times to apply the hashing function. This forked version is available <a href="https://github.com/Phyks/bloomfilter.js/blob/master/bloomfilter.js">here</a>.</p>
  74. <p>Then, I reimplemented this library in Python, to generate readable Bloom filters for the JavaScript script.</p>
  75. <h3>Server side</h3>
  76. <p>The generation script takes every articles in a given directory and for each of them:</p>
  77. <ol>
  78. <li>It gets a set of all the words in this article, ignoring too short words. </li>
  79. <li>It applies <a href="http://tartarus.org/martin/PorterStemmer/">Porter Stemming Algorithm</a> to reduce drastically the number of words to keep. </li>
  80. <li>It generates a Bloom filters containing all of these words.</li>
  81. </ol>
  82. <p>Finally, it concatenates all the per article Bloom filters in a binary file, to be sent to the client. It also generates a JSON index mapping the id of the Bloom filter in the binary file to the corresponding URL and title for each article.</p>
  83. <h3>Client side</h3>
  84. <p>Upon loading, the JavaScript script downloads the binary file (see <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data">this MDN doc</a> for more details) containing the Bloom filters and the JSON index, and regenerate BloomFilters on the client side.</p>
  85. <p>When the client searches for something, the JavaScript script splits the query in words and iterate over the Bloom filters to search for the words. That's it =)</p>
  86. <h2>(Fun) facts found while reimplementing the Bloom filters library in Python</h2>
  87. <p>First problem I had to deal with : the difference between JavaScript <code>Number</code> type and Python <code>int</code>. JavaScript has only one type for all numbers (<code>int</code> or <code>floats</code>) and it is <code>Number</code> (see <a href="https://stackoverflow.com/questions/307179/what-is-javascripts-highest-integer-value-that-a-number-can-go-to-without-losin">this SO thread</a>). They are 64-bit floating point values, with a magnitude no greater than 2<sup>53</sup>. However, when doing bitwise operations, they are casted to 32 bits before doing the operation. This is something to take care of, because Python's <code>int</code> can be 64 bits (<a href="http://legacy.python.org/dev/peps/pep-0237/">http://legacy.python.org/dev/peps/pep-0237/</a>). Then, when a bitwise operation overflows in JavaScript, it may not overflow the same way in Python.</p>
  88. <p>The solution to this problem was to use <code>ctypes.c_int</code> in Python for bitwise operations, as proposed <a href="https://stackoverflow.com/questions/1694507/difference-between-operator-in-js-and-python">here</a>.</p>
  89. <p>Another problem was the difference between modulo behaviour with negative numbers in Python and in JavaScript. Unlike C, C++ and JavaScript, Python's modulo operator (%) always return a number having the same sign as the divisor (<a href="https://stackoverflow.com/questions/3883004/negative-numbers-modulo-in-python">Source</a>). Then, we have to reimplement the C behaviour in a modulo function in Python.</p>
  90. <p>Finally, there was no “shift right adding zeros” (logical right shift) in Python, contrary to JS, see <a href="https://stackoverflow.com/questions/5832982/how-to-get-the-logical-right-binary-shift-in-python">this SO thread</a>. </p>
  91. <footer>
  92. <p class="tags">Tags : <a href="http://phyks.me/tags/Dev.html">Dev</a>, <a href="http://phyks.me/tags/Web.html">Web</a></p></footer>
  93. </div>]]></content:encoded>
  94. <pubDate>Sat, 08 Nov 2014 16:45:00 -0000</pubDate>
  95. <category>Dev</category>
  96. <category>Web</category>
  97. <author>webmaster@phyks.me (Phyks)</author>
  98. </item>
  99. <item>
  100. <title>Balancer le son de ses hauts-parleurs sur le réseau</title>
  101. <link>http://phyks.me/2014/10/pulseaudio_remote.html</link>
  102. <guid isPermaLink="true">http://phyks.me/2014/10/pulseaudio_remote.html</guid>
  103. <description>J'ai un PC fixe et un portable, et je cherchais un moyen de balancer le son de mon portable sur les hauts-parleurs de bonne qualité branchés sur mon PC fixe, quand je suis sur le même résea…</description>
  104. <content:encoded><![CDATA[<div class="article">
  105. <header></header>
  106. <!--
  107. @author=Phyks
  108. @date=26102014-2240
  109. @title=Balancer le son de ses hauts-parleurs sur le réseau
  110. @tags=Arch, Linux
  111. -->
  112. <p>J'ai un PC fixe et un portable, et je cherchais un moyen de balancer le son de mon portable sur les hauts-parleurs de bonne qualité branchés sur mon PC fixe, quand je suis sur le même réseau. Et en fait, c'est très simple à faire avec PulseAudio.</p>
  113. <h2>La première méthode, simple, qui marche partout</h2>
  114. <p>S'assurer d'avoir <code>pulseaudio</code> configuré sur ses ordinateurs, et installer <code>paprefs</code>. Lancer <code>paprefs</code> et dans l'onglet <code>Multicast/RTP</code>, cocher la case <em>receiver</em> sur le PC sur lequel les hauts-parleurs sont branchés, et la case <em>sender</em> sur l'autre.</p>
  115. <p>Sur le PC qui envoie la musique (<em>sender</em>), vous avez le choix entre trois options, dont seulement deux nous intéressent : <code>Send audio from local speakers</code> (qui enverra tout le son local sur les hauts-parleurs distants) et <code>Create separate audio device for Multicast/RTP</code> (qui vous rajoutera une sortie son <code>Multicast/RTP</code> que vous pourrez utiliser ou non, par application).</p>
  116. <p>Si vous n'avez pas de pare-feu et que vous êtes bien sur le même réseau, c'est tout ce que vous avez à faire !</p>
  117. <p>Par contre, vous remarquerez vite que la qualité n'est pas top (au moins chez moi) : un bon FLAC d'un côté ressort vite comme un MP3 64k d'il y a quelques années de l'autre côté…</p>
  118. <h2>La deuxième solution, encore plus simple, qui marche mieux !</h2>
  119. <p>La deuxième solution consiste à utiliser les deux premiers onglets de <code>paprefs</code> : <code>Network Access</code> et <code>Network Server</code>.</p>
  120. <p>Sur le PC qui envoie le son, cochez la case <code>Make discoverable PulseAudio network sound devices available locally</code> dans le premier onglet.</p>
  121. <p>Sur le PC qui reçoit le son, cochez les trois premières cases (<code>Activer l'accès réseau aux périphériques de son locaux</code>).</p>
  122. <p>Et c'est tout =) Vous aurez désormais les sorties audio de votre autre PC qui apparaîtront chez vous (par exemple dans <code>Audio -&gt; Périphérique audio</code> dans VLC). Et pour le coup, plus aucun problème de qualité à signaler ! Testé en filaire, et aucun problème de débit / lag / son à signaler pour l'instant.</p>
  123. <p>À noter cependant que chez moi, j'ai deux sorties qui sont disponibles, une appelée <code>Audio interne…</code> et l'autre appelée <code>Simultaneous output to Audio interne…</code>. Si j'utilise la deuxième, j'ai le son qui saute, et c'est inutilisable, mais la première fonctionne nickel.</p>
  124. <h2>Références</h2>
  125. <p>Principalement un seul lien : <a href="http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Network/#index2h3">http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Network/#index2h3</a>. Mais ils font tout à coup de ligne de commande et c'est en fait bien plus simple de passer par paprefs. </p>
  126. <footer>
  127. <p class="tags">Tags : <a href="http://phyks.me/tags/Arch.html">Arch</a>, <a href="http://phyks.me/tags/Linux.html">Linux</a></p></footer>
  128. </div>]]></content:encoded>
  129. <pubDate>Sun, 26 Oct 2014 20:40:00 -0000</pubDate>
  130. <category>Arch</category>
  131. <category>Linux</category>
  132. <author>webmaster@phyks.me (Phyks)</author>
  133. </item>
  134. <item>
  135. <title>Utiliser son PC sous Arch pour connecter un Raspberry Pi à Internet</title>
  136. <link>http://phyks.me/2014/10/dhcp_server.html</link>
  137. <guid isPermaLink="true">http://phyks.me/2014/10/dhcp_server.html</guid>
  138. <description>J'ai un Raspberry Pi et mon portable sous Arch Linux, et je me promène pas mal avec les deux. Mais je n'ai pas toujours de routeur à disposition pour brancher les deux sur le même réseau et travailler facilemen…</description>
  139. <content:encoded><![CDATA[<div class="article">
  140. <header></header>
  141. <!--
  142. @author=Phyks
  143. @date=18102014-2240
  144. @title=Utiliser son PC sous Arch pour connecter un Raspberry Pi à Internet
  145. @tags=Arch, Dev, Linux
  146. -->
  147. <p>J'ai un Raspberry Pi et mon portable sous Arch Linux, et je me promène pas mal avec les deux. Mais je n'ai pas toujours de routeur à disposition pour brancher les deux sur le même réseau et travailler facilement. Il est très simple de mettre en place en 5 minutes une configuration me permettant de connecter le Raspberry Pi sur mon portable, et de partager la connexion Internet issue du wifi de mon PC avec le Raspberry Pi. Comme ça, plus de problèmes, je peux bosser sur le Raspberry Pi n'importe où.</p>
  148. <p>C'est parti !</p>
  149. <p><em>Note</em> : J'utilise cette configuration pour développer, et elle n'est donc pas forcément optimale et devrait sûrement être adaptée pour être utilisée en production.</p>
  150. <h2>Installation d'un serveur dhcp sur le portable</h2>
  151. <p>Commençons par installer un serveur dhcp sur le PC avec Arch, pour éviter de devoir saisir une adresse IP fixe sur le Raspberry Pi. Comme ça, on peut utiliser n'importe quelle image sans réfléchir, comme si on avait un routeur qui va bien.</p>
  152. <p>Le plus simple est de suivre <a href="https://wiki.archlinux.org/index.php/Dhcpd">cette page de la documentation</a>.</p>
  153. <ol>
  154. <li>On attribue une adresse IP fixe à l'interface ethernet (ici 192.168.192.1, attention à ce que ça ne rentre pas en conflit avec votre configuration réseau).</li>
  155. </ol>
  156. <pre><code>ip link set up dev enp4s0f2
  157. ip addr add 192.168.192.1/24 dev enp4s0f2
  158. </code></pre>
  159. <ol>
  160. <li>
  161. <p>Déplacer le fichier <code>/etc/dhcpd.conf</code> fourni par défaut vers <code>/etc/dhcpd.conf.example</code> pour pouvoir le modifier sereinement.</p>
  162. </li>
  163. <li>
  164. <p>Éditer le fichier <code>/etc/dhcpd.conf</code>. À titre indicatif, voici le mien :</p>
  165. </li>
  166. </ol>
  167. <pre><code>option domain-name-servers 8.8.8.8, 8.8.4.4;
  168. option subnet-mask 255.255.255.0;
  169. option routers 192.168.192.1;
  170. subnet 192.168.192.0 netmask 255.255.255.0 {
  171. range 192.168.192.10 192.168.192.20;
  172. }
  173. </code></pre>
  174. <p>Je spécifie d'utiliser les serveurs DNS de Google (qui sont disponibles partout -si vous avez un serveur sur votre ordinateur, vous pouvez le mettre à la place), que le routeur est à l'adresse <code>192.168.192.1</code> et que j'attribue des adresses dans la gamme <code>192.168.192.10-192.168.192.20</code>.</p>
  175. <ol>
  176. <li>Vous pouvez lancer le service dhcpd avec <code>systemctl start dhcpd4</code>. Je préfèrais restreindre l'interface sur laquelle le serveur DHCP tournait, pour ne l'utiliser que sur l'interface ethernet. Pour se faire, il suffit de suivre les instructions « Listening on only one interface - Service file » de la <a href="https://wiki.archlinux.org/index.php/Dhcpd">documentation Arch Linux</a>.</li>
  177. </ol>
  178. <h2>Configuration du pare-feu et du noyau</h2>
  179. <p>Il faut ensuite configurer <code>iptables</code> et le noyau pour rediriger les paquets réseau vers le Raspberry Pi.</p>
  180. <p>Pour ce faire,</p>
  181. <pre><code>iptables -A FORWARD -o wlp3s0 -i enp4s0f2 -s 192.168.192.1/24 -m conntrack --ctstate NEW -j ACCEPT
  182. iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
  183. iptables -A POSTROUTING -t nat -j MASQUERADE
  184. </code></pre>
  185. <p>et on dit active le <em>forwarding</em> dans le noyau :</p>
  186. <pre><code>echo 1 | tee /proc/sys/net/ipv4/ip_forward
  187. </code></pre>
  188. <h2>Le script qui va bien</h2>
  189. <p>Une fois le serveur <code>dhcpd</code> configuré, <a href="https://snippet.phyks.me/?snippet=5442cd90a8204">ce script</a> permet de tout démarrer / arrêter.</p>
  190. <p>Attention, le <em>flush</em> dans la fonction <code>stop</code> peut être trop brutal pour vous. </p>
  191. <footer>
  192. <p class="tags">Tags : <a href="http://phyks.me/tags/Arch.html">Arch</a>, <a href="http://phyks.me/tags/Dev.html">Dev</a>, <a href="http://phyks.me/tags/Linux.html">Linux</a></p></footer>
  193. </div>]]></content:encoded>
  194. <pubDate>Sat, 18 Oct 2014 19:40:00 -0000</pubDate>
  195. <category>Arch</category>
  196. <category>Dev</category>
  197. <category>Linux</category>
  198. <author>webmaster@phyks.me (Phyks)</author>
  199. </item>
  200. <item>
  201. <title>Sortez vos emails, c'est pas sale !</title>
  202. <link>http://phyks.me/2014/08/sortez_vos_emails.html</link>
  203. <guid isPermaLink="true">http://phyks.me/2014/08/sortez_vos_emails.html</guid>
  204. <description>TLDR in English : If you care about your scripts, if you love them and want them to be used, to live, leave a simple way to contact you (…</description>
  205. <content:encoded><![CDATA[<div class="article">
  206. <header></header>
  207. <!--
  208. @author=Phyks
  209. @date=07082014-2315
  210. @title=Sortez vos emails, c'est pas sale&nbsp;!
  211. @tags=Libre, Dev
  212. -->
  213. <p><em>TLDR in English</em> : If you care about your scripts, if you love them and want them to be used, to live, <em>leave</em> a simple way to contact you (a.k.a. an email address which has always been working, works and will be always working, because email protocol is an <a href="https://en.wikipedia.org/wiki/Internet_Standard">Internet Standard</a>). I'm fed up with trying to find you and spend an incredible amount of time doing so…</p>
  214. <p>Je vois de plus en plus de gens qui font un script, souvent fort utile, et qui le balancent dans un coin, sur Github, sur Sourceforge ou autre. Problème : ils ne laissent aucun moyen décent de les contacter (un email quoi !). Du coup, très souvent :</p>
  215. <ul>
  216. <li>
  217. <p>On veut réutiliser le script mais il n'y a pas de licence… Tant pis, il n'y a plus <em>aucun</em> moyen de contacter l'auteur.</p>
  218. </li>
  219. <li>
  220. <p>Il y a une faille très grave dans le code, qu'on ne veut pas diffuser dans les <em>issues</em> Github pour ne pas la rendre directement publique, tant pis, il n'y a pas moyen… Ça sera public ou rien (et encore, quelques fois c'est rien du tout car les <em>issues</em> ne sont pas activées…)</p>
  221. </li>
  222. <li>
  223. <p>Ou alors l'auteur laisse un pseudo, un lien vers un site web, une liste de "comptes en ligne"… mais aucun email. Je n'ai <em>pas</em> de compte Twitter, je n'ai <em>pas</em> de compte Facebook/Hangout whatever, j'ai depuis peu un compte Diaspora*, mais un email, tout le monde peut l'utiliser, l'utilise depuis 30 ans, et l'utilisera sûrement dans 30 ans. C'est tellement plus simple… mais non, on liste tous ses comptes sur les rezosocios.</p>
  224. </li>
  225. </ul>
  226. <p>Du coup, j'en ai marre de courir derrière les gens, à essayer de croiser des comptes jusqu'à avoir une adresse email, qui bien souvent n'est plus utilisée. Sur les derniers scripts que j'ai réutilisé, 9 fois sur 10, ça s'est passé comme ceci :</p>
  227. <ul>
  228. <li>Je trouve un script sur Github, sans licence… J'ai besoin de le réutiliser, et j'ai la flemme de le réécrire. Je cherche un contact.</li>
  229. <li>J'atterris sur le profil Github de l'auteur, aucune adresse email, rien… Je n'ai que le pseudo et les autres projets de l'auteur (qui bien souvent sont inexistants en fait).</li>
  230. <li>Je cherche sur <del>Google</del> avec l'auteur, deux possibilités :<ul>
  231. <li>Je tombe sur un site perso, une adresse email est présente (rarissime)</li>
  232. <li>Je tombe sur un site perso, une liste de comptes en ligne est présente… retour à la case départ.</li>
  233. <li>Je ne peux que me fier aux comptes retournés par <del>Google</del>. Je n'ai aucune manière d'être sûr que les liens identifient la même personne… Je trouve rarement une adresse email.</li>
  234. </ul>
  235. </li>
  236. </ul>
  237. <p><em>Conclusion</em> : Si vous tenez à vos scripts, que vous les aimez et que vous voulez les voir servir, être réutilisés et vivre, <em>laissez</em> un moyen simple de vous contacter (un <em>email</em>, ça marche, ça a toujours marché et ça marchera toujours, c'est l'avantage des <a href="https://en.wikipedia.org/wiki/Internet_Standard">protocoles standards</a>). J'en ai marre de vous courir après… Et s'il n'y en a pas, tant pis, j'irai plus vite à réécrire votre code qu'à essayer de vous retrouver.</p>
  238. <p>EDIT: Ou alors, mettez au moins votre script sous WTFPL qu'on puisse le réutiliser sans problèmes =)</p>
  239. <p>EDIT 2: Ouais, il peut y avoir un email dans l'historique de git. Mais c'est pas toujours le cas, les emails ne sont pas à jour, et c'est spécifique à git (alors que les scripts peuvent être n'importe où). </p>
  240. <footer>
  241. <p class="tags">Tags : <a href="http://phyks.me/tags/Libre.html">Libre</a>, <a href="http://phyks.me/tags/Dev.html">Dev</a></p></footer>
  242. </div>]]></content:encoded>
  243. <pubDate>Thu, 07 Aug 2014 20:15:00 -0000</pubDate>
  244. <category>Libre</category>
  245. <category>Dev</category>
  246. <author>webmaster@phyks.me (Phyks)</author>
  247. </item>
  248. <item>
  249. <title>Synchroniser ses ordinateurs 1/2</title>
  250. <link>http://phyks.me/2014/08/synchronisation_backups_1.html</link>
  251. <guid isPermaLink="true">http://phyks.me/2014/08/synchronisation_backups_1.html</guid>
  252. <description>Étude des solutions disponibles
  253. J'utilise quotidiennement au moins 2 ordinateurs : mon ordinateur portable et mon fix…</description>
  254. <content:encoded><![CDATA[<div class="article">
  255. <header></header>
  256. <!--
  257. @author=Phyks
  258. @date=07082014-2230
  259. @title=Synchroniser ses ordinateurs 1/2
  260. @tags=Autohébergement, Phyks, Libre, Linux
  261. -->
  262. <h2>Étude des solutions disponibles</h2>
  263. <p>J'utilise quotidiennement au moins 2 ordinateurs : mon ordinateur portable et mon fixe. Tous les deux ont des gros disques durs (&gt; 1 To) et je cherche depuis quelques temps à les synchroniser pour les utiliser de façon totalement transparente avec mes fichiers (et avec la configuration utilisateur de base, tel que mon <code>.vimrc</code>, mon thème pour <code>rxvt-unicode</code>, etc.).</p>
  264. <p>J'ai également un gros disque dur externe, sur lequel je veux faire des <em>backups</em> complets réguliers de certains fichiers.</p>
  265. <p>Je dois donc maintenir en permanence 3 disques durs synchronisés : celui de mon ordinateur fixe, de mon portable et mon disque dur externe. Faire ça à la main, c'est très long et fastidieux (et potentiellement compliqué). Je cherche donc un moyen d'automatiser tout ça proprement. De plus, j'ai un serveur dédié, avec de l'espace disque disponible, sur lequel je voudrais stocker une partie des sauvegardes, pour avoir un <em>backup</em> décentralisé en cas de pépin.</p>
  266. <p>Les solutions à envisager doivent répondre aux critères suivants :</p>
  267. <ul>
  268. <li>Pouvoir facilement choisir les dossiers et les fichiers à synchroniser et être capable de synchroniser de gros fichiers sans problèmes et dans des temps décents. Je veux synchroniser tout mon <em>home</em> entre mes deux ordinateurs et mon disque dur externe, mais je ne veux pas synchroniser toutes mes musiques et vidéos avec mon serveur, pour ne pas le saturer inutilement. J'ai pas mal de scripts déjà versionnés par Git également, que je veux pouvoir exclure facilement.</li>
  269. <li>Proposer une solution de sauvegarde chiffrée (transferts chiffrés entre les postes et chiffrement de mes données sur mes serveurs).</li>
  270. <li>Permettre une architecture décentralisée, pas besoin de repasser par mon serveur pour synchroniser mes postes quand ils sont sur le même réseau local.</li>
  271. </ul>
  272. <p>J'ai également repéré trois solutions potentielles : <a href="http://www.cis.upenn.edu/~bcpierce/unison/">Unison</a>, <a href="http://syncthing.net/">Syncthing</a> trouvé grâce à <a href="http://tomcanac.com/blog/2014/07/14/syncthing-alternative-libre-btsync/">cet article de tmos</a> et <a href="http://git-annex.branchable.com/">git-annex</a> trouvé par <a href="http://flo.fourcot.fr/index.php?post/2013/07/19/J-ai-d%C3%A9couvert-git-annex">cet article</a>. (Je cherche bien sûr une solution <em>opensource</em> à installer sur mon serveur)</p>
  273. <h3>Unison</h3>
  274. <p><a href="http://www.cis.upenn.edu/~bcpierce/unison/">Unison</a> est un programme de synchronisation de fichier multiplateforme, écrit en Ocaml. Il gère les conflits automatiquement si possible, et avec intervention de l'utilisateur si besoin. Il prend un grand soin à laisser les systèmes en état fonctionnel à chaque instant, pour pouvoir récupérer facilement en cas de problèmes. Par contre, le projet était un projet de recherche initialement, et avait donc un développement très actif. Ce n'est plus le cas, et le développement est beaucoup moins actif, comme expliqué <a href="http://www.seas.upenn.edu/~bcpierce/unison//status.html">sur la page du projet</a>.</p>
  275. <p>Autre limitation : il n'est possible de synchroniser que des <em>paires</em> de machines avec Unison. Cela veut dire que pour synchroniser mes 3 machines, je vais devoir utiliser une configuration en étoiles, en passant forcément par mon serveur. C'est pas top car mon portable et mon ordinateur fixe étant très souvent sur le même réseau, il peut être intéressant de s'affranchir du serveur dans ce cas, pour avoir des taux de transfert plus élevés.</p>
  276. <p>Enfin, il semble assez non trivial d'avoir un chiffrement des données synchronisées, et ce n'est pas implémenté directement par Unison. Il faut donc rajouter une couche d'Encfs ou autre. <a href="https://bbs.archlinux.org/viewtopic.php?pid=1317177#p1317177">Une discussion sur le forum archlinux</a> (en anglais) évoque cette possibilité, et <a href="http://www.mail-archive.com/encfs-users@lists.sourceforge.net/msg00164.html">un post</a> sur la mailing-list [Encfs-users] donne quelques détails supplémentaires.</p>
  277. <h3>Syncthing</h3>
  278. <p>(Je reprends les informations du <a href="http://syncthing.net/">site officiel</a> et de <a href="http://tomcanac.com/blog/2014/07/14/syncthing-alternative-libre-btsync/">l'article de Tom</a>.)</p>
  279. <p>Syncthing est écrit en Go. Toutes les communications sont chiffrées par TLS et chaque nœud est authentifié et doit être explicitement ajouté pour pouvoir accéder aux fichiers. Syncthing utilise donc son propre protocole, et sa propre authentification. Il est multiplateforme, a une très jolie interface et ne requiert aucune configuration particulière (il est censé fonctionner <em>out of the box</em>, en utilisant uPnP si besoin pour ne pas avoir besoin de mettre en place de translation de port).</p>
  280. <p>Chaque machine peut échanger avec toutes les machines avec lesquelles il y a eu un échange d'identifiants. On peut donc très facilement choisir de construire une architecture centralisée ou décentralisée (dans le premier cas, toutes les machines n'auront que l'identifiant du serveur central, dans le deuxième cas toutes les machines auront les identifiants de toutes les autres).</p>
  281. <p>Toute la configuration se fait par une jolie interface web, protégée par mot de passe. Vous pouvez partager chaque dossier comme bon vous semble, et vous pouvez même partager certains dossiers avec des personnes extérieures, à la dropbox, sans dropbox :). Et de par l'architecture du logiciel, il n'y a pas de <em>serveur</em> ni de <em>client</em> mais un seul logiciel qui tourne partout.</p>
  282. <p><img alt="La jolie interface de Syncthing" src="http://phyks.me/2014/08/syncthing.png"/></p>
  283. <p>Le code est disponible sur <a href="https://github.com/syncthing/syncthing">Github</a>, le dépôt est actif et les tags sont signés.</p>
  284. <p>Il satisfait donc a priori la plupart de mes besoins. Il faut juste que je trouve un moyen de chiffrer mes documents sur mon serveur (mes disques sont déjà chiffrés, mais je voudrais avoir un gros conteneur déchiffré à chaque synchronisation, et verrouillé après idéalement). Apparemment, c'est <a href="https://github.com/syncthing/syncthing/issues/109">en cours de discussion</a>.</p>
  285. <p>Concernant la gestion des conflits, elle n'a pas l'air parfaite, comme le montre <a href="https://github.com/syncthing/syncthing/issues/220">cette <em>issue</em></a> sur Github. Il semblerait que la politique actuelle soit <em>newest wins</em> ce qui peut causer des pertes de données (une copie de sauvegarde est peut être réalisée, car SyncThing peut versionner les fichiers, mais je ne suis pas sûr de ce point, à tester).</p>
  286. <h3>Git-annex</h3>
  287. <p><a href="http://git-annex.branchable.com/">Git-annex</a> est un programme permettant de synchroniser ses fichiers en utilisant Git. En fait, il est vu comme un plugin pour Git, et il va stocker les fichiers dans un dépôt Git, mais ne pas versionner leur contenu. Du coup, on évite de devoir versionner des gros fichiers et donc les problèmes habituels de Git avec des gros fichiers potentiellement binaires.</p>
  288. <p>C'est certainement le programme le plus abouti des trois présentés ici, son développement est actif, il y a une communauté derrière (et du monde sur IRC !) et le développeur a réussi une campagne Kickstarter l'an dernier pour se financer pour travailler sur le logiciel pendant un an. Il a notamment implémenté un assistant web dernièrement, permettant de gérer ses synchronisations <em>via</em> une interface web fort jolie à la Syncthing, en s'affranchissant de la ligne de commande. Je pense quand même que Syncthing est plus <em>user friendly</em>.</p>
  289. <p>Les possibilités du logiciel, listées sur <a href="http://git-annex.branchable.com">la page du projet</a> sont assez impressionnantes. Parmi les fonctionnalités avancées :</p>
  290. <ul>
  291. <li>
  292. <p>Possibilité d'avoir tous les fichiers listés partout, même si leur contenu n'est pas effectivement présent sur le disque. Du coup, git-annex sait où aller chercher chaque fichier pour nous aider à nous y retrouver avec plusieurs supports de stockage (plusieurs disques durs externes de <em>backup</em> par exemple)</p>
  293. </li>
  294. <li>
  295. <p>Git-annex utilise des dépôts standards, ce qui permet d'avoir un dépôt toujours utilisable, même si Git et Git-annex tombent dans l'oubli.</p>
  296. </li>
  297. <li>
  298. <p>Il peut gérer autant de clones qu'on veut, et peut donc servir à synchroniser selon l'architecture qu'on veut. Il est capable d'attribuer des poids différents à chaque source, ce qui veut dire que je peux synchroniser mes ordinateurs <em>via</em> mon serveur, et si jamais ils sont sur le même réseau local, je peux synchroniser directement sans passer par mon serveur.</p>
  299. </li>
  300. <li>
  301. <p>Il gère plusieurs possibilités de chiffrement, pour chiffrer les copies distantes, sur mon serveur par exemple. Et il permet de chiffrer tout en partageant entre plusieurs utilisateurs. Il peut utiliser d'office un serveur distant tel qu'un serveur sur lequel on a un accès SSH (et les transferts sont immédiatement chiffrés par SSH du coup) ou encore un serveur Amazon S3.</p>
  302. </li>
  303. <li>
  304. <p>Possibilité de partager des fichiers avec des amis en utilisant un serveur tampon. Ce serveur stocke uniquement les fichiers en cours de transfert et n'a donc pas besoin d'un espace disque considérable.</p>
  305. </li>
  306. <li>
  307. <p>Il gère les conflits.</p>
  308. </li>
  309. <li>
  310. <p>Il peut utiliser des <em>patterns</em> pour exclure des fichiers, ou les inclure au contraire. On peut faire des requêtes complètes telles que "que les MP3 et les fichiers de moins de N Mo".</p>
  311. </li>
  312. <li>
  313. <p>Bonus : il peut être utilisé pour servir un dossier semblable à mon <a href="http://pub.phyks.me">pub.phyks.me</a>, que j'implémenterai sûrement du coup, pour permettre de cloner tout mon <code>pub</code> directement.</p>
  314. </li>
  315. </ul>
  316. <p>Plusieurs <em>screencasts</em> sont disponibles dans la <a href="http://git-annex.branchable.com/assistant/">documentation</a> et un retour en français est disponible <a href="http://flo.fourcot.fr/index.php?post/2013/07/19/J-ai-d%C3%A9couvert-git-annex">ici</a>.</p>
  317. <p>Ses points forts ont vraiment l'air d'être ses fonctions avancées et la possibilité de gérer finement la localisation des fichiers. Git-annex ne se contente pas de vous permettre de synchroniser des fichiers, mais aussi de les déplacer géographiquement, partager et sauvegarder.</p>
  318. <h2>Conclusion (temporaire)</h2>
  319. <p>J'ai repéré trois solutions envisageables pour l'instant : Unison, SyncThing et git-annex, par ordre de fonctionnalités. Les informations précédentes sont uniquement issues des articles, documentations et retours d'utilisateurs. SyncThing a l'air le plus <em>user friendly</em> de tous, et il a des fonctionnalités intéressantes et avancées. git-annex est clairement celui qui a le plus de fonctionnalités, mais il est donc également plus compliqué à prendre en main.</p>
  320. <p>Après cette analyse, je pense donc partir sur git-annex pour mettre en place mes sauvegardes. Rendez-vous bientôt pour la deuxième partie de cet article, avec un retour complet sur ma procédure de synchronisation (dans quelques temps quand même… faut que je réfléchisse à mon truc et que je dompte git-annex =).</p>
  321. <h2>Notes</h2>
  322. <ul>
  323. <li>
  324. <p>Après réflexion, utiliser le disque dur externe en plus fait beaucoup de redondance. Du coup, si je ne peux synchroniser qu'une partie de mes fichiers sur celui-ci, c'est encore mieux (par exemple que ma bibliothèque de musiques / films).</p>
  325. </li>
  326. <li>
  327. <p>Une autre solution qui pourrait vous intéresser est <a href="https://tahoe-lafs.org/trac/tahoe-lafs">Tahoe-LAFS</a> qui distribue vos fichiers sur plusieurs serveurs de sorte qu'aucun serveur ne puisse connaître vos données, et que si un serveur est en panne, vous puissiez toujours les récupérer (par défaut il utilise 10 nœuds pour le stockage et ne nécessite que 3 nœuds pour reconstituer les données, si j'ai bien compris). Voir aussi <a href="http://numaparis.ubicast.tv/videos/rozofs/">cette vidéo sur rozoFS</a> à PSES 2014, pour avoir une idée de comment cela fonctionne.</p>
  328. </li>
  329. <li>
  330. <p>Un <code>rsync</code> basique ne me suffit pas, car je dois pouvoir gérer des modifications des deux côtés de la connexion à la fois, et pouvoir gérer les conflits.</p>
  331. </li>
  332. </ul>
  333. <footer>
  334. <p class="tags">Tags : <a href="http://phyks.me/tags/Autohébergement.html">Autohébergement</a>, <a href="http://phyks.me/tags/Phyks.html">Phyks</a>, <a href="http://phyks.me/tags/Libre.html">Libre</a>, <a href="http://phyks.me/tags/Linux.html">Linux</a></p></footer>
  335. </div>]]></content:encoded>
  336. <pubDate>Thu, 07 Aug 2014 19:30:00 -0000</pubDate>
  337. <category>Autohébergement</category>
  338. <category>Phyks</category>
  339. <category>Libre</category>
  340. <category>Linux</category>
  341. <author>webmaster@phyks.me (Phyks)</author>
  342. </item>
  343. <item>
  344. <title>Les énigmes du réseau Free Mobile</title>
  345. <link>http://phyks.me/2014/08/free_mobile_fluctuant.html</link>
  346. <guid isPermaLink="true">http://phyks.me/2014/08/free_mobile_fluctuant.html</guid>
  347. <description>C'est très étrange… Là où je suis, la connexion SSH est toujours utilisable (avec un lag important rendant très insupportable toute édition de fichiers, mais Weechat over SSH est utilisable), mais le débit sur le port 80 est très fluctuan…</description>
  348. <content:encoded><![CDATA[<div class="article">
  349. <header></header>
  350. <!--
  351. @author=Phyks
  352. @date=04082014-0005
  353. @title=Les énigmes du réseau Free Mobile
  354. @tags=Phyks
  355. -->
  356. <p>C'est très étrange… Là où je suis, la connexion SSH est toujours utilisable (avec un lag important rendant très insupportable toute édition de fichiers, mais Weechat <em>over</em> SSH est utilisable), mais le débit sur le port 80 est très fluctuant. Quelques fois les pages se chargent très rapidement, quelques fois il n'y a pas moyen de charger une seule page, même après 10 minutes d'attente et trois tentatives (indépendamment du domaine, donc pas un problème de <em>peering</em> <em>a priori</em>).</p>
  357. <p>Par contre, passer sa connexion web dans un tunnel SOCKS améliore grandement les choses. Et de façon générale, j'ai déjà remarqué ça à plusieurs reprises sur des connexion lentes (Free Mobile, mais aussi certains hotspots etc.). À 18h, la connexion est toujours inutilisable, mais ça rend la connexion internet utilisable le reste du temps.</p>
  358. <p>Je précise que je suis dans une zone censée être couverte en <em>H+</em> (je le cherche encore le fabuleux débit promis par toutes les dernières technos, quand en HSDPA, j'ai tout juste un débit d'EDGE) et encore loin de mon plafond mensuel de 3Go (et de toutes façons, le même comportement est observé avec des clients utilisant peu la 3G)… qu'est-ce que ça va être après ?</p>
  359. <p>Du coup, Free bride-t-il le port 80 ? Ou l'antenne est-elle surchargée (par des gens qui font du web, donc du port 80) ? Ça m'étonne quand même cette différence <strong>significative</strong> de débit selon les ports utilisés (à titre de comparaison, je ne pouvais pas mettre à jour mon système avec <code>yaourt</code> tout à l'heure, débit trop faible, mais un téléchargement de quelques mégaoctets dans mon Firefox sur proxy SOCKS se faisait en un temps « raisonnable » et je peux récupérer mes emails par POP/IMAP sans problème).</p>
  360. <p>Bref, c'est pas la première fois que je remarque ça, et heureusement j'ai la possibilité de faire un tunnel SOCKS sur mon kimsufi, mais comment fait Madame Michu ?! Et surtout… pourquoi ce comportement si étrange sur le port 80 ?</p>
  361. <p>P.S. : J'ai pensé au début que c'était Orange qui bridait le débit des abonnés Free sur ses antennes, me rappelant d'histoires similaires au lancement, et confirmé par un portable chez Sosh qui tourne sans problème. Mais il semblerait que je sois sur une antenne Free…</p>
  362. <footer>
  363. <p class="tags">Tags : <a href="http://phyks.me/tags/Phyks.html">Phyks</a></p></footer>
  364. </div>]]></content:encoded>
  365. <pubDate>Sun, 03 Aug 2014 21:05:00 -0000</pubDate>
  366. <category>Phyks</category>
  367. <author>webmaster@phyks.me (Phyks)</author>
  368. </item>
  369. <item>
  370. <title>Recevoir ses emails par SMS avec Free Mobile</title>
  371. <link>http://phyks.me/2014/07/notification_sms_free.html</link>
  372. <guid isPermaLink="true">http://phyks.me/2014/07/notification_sms_free.html</guid>
  373. <description>Edit : Cela fait bientôt une semaine que l'API Free me renvoie un 402, en boucle… je ne peux plus envoyer de SMS depuis l'AP…</description>
  374. <content:encoded><![CDATA[<div class="article">
  375. <header></header>
  376. <!--
  377. @author=Phyks
  378. @date=30072014-1500
  379. @title=Recevoir ses emails par SMS avec Free Mobile
  380. @tags=Dev, Phyks
  381. -->
  382. <p><em>Edit</em> : Cela fait bientôt une semaine que l'API Free me renvoie un 402, en boucle… je ne peux plus envoyer de SMS depuis l'API. Je ne sais pas combien de temps ça va durer, à suivre… mais du coup c'était pas forcément une super idée… soyez prévenus ! :)</p>
  383. <p>Si vous êtes client Free Mobile (forfait à 2€ ou à 19€), sachez que Free met à disposition gratuitement une <a href="http://www.freenews.fr/spip.php?article14817">API d'envoi de SMS</a>. <em>Via</em> un appel HTTP, vous pourrez désormais vous envoyer des notifications par SMS (uniquement à destination de votre numéro donc), ce qui fait le plus grand bonheur des utilisateurs de solutions domotiques.</p>
  384. <p>Dans cet article, je vais l'utiliser dans un but différent : recevoir mes emails par SMS. Je pars d'ici peu pour une semaine à l'étranger (pas de connexion internet…) et ai besoin de relever mes emails régulièrement. Grâce à ce service, je vais pouvoir les recevoir par SMS.</p>
  385. <p><em>Note</em> : Recevoir ses emails par SMS peut poser des problèmes de vie privée, votre opérateur voyant passer tous vos SMS notamment. Ça peut être d'autant plus gênant si vous recevez des rappels de mot de passe par email, qui vous seront transmis par SMS.</p>
  386. <p>Je me suis grandement inspiré de <a href="http://louis.jachiet.com/blog/?p=228">cet article</a> mais ai réécrit le script. Le script ci-dessous est donc en Python (que je maîtrise mieux que Perl), gère plusieurs serveurs et se connecte en IMAP à vos boîtes, pour pouvoir récupérer des emails chez Gmail and cie, pour lesquels on ne peut pas mettre de règles <code>procmail</code>. Dans mon script, les identifiants / mots de passe sont en clair pour pouvoir l'éxecuter <em>via</em> une <code>crontask</code>. Si vous ne contrôlez pas le serveur sur lequel vous faites tourner ce script ou ne réglez pas correctement les permissions, attention à vos mots de passe !</p>
  387. <p>Première étape, il faut aller activer l'option sur votre compte. Sur le site de Free, Gérer mon compte → Mes Options → Notifications par SMS → Activer. Vous pourrez alors récupérer votre clé d'API.</p>
  388. <p>Deuxième étape, récupérer <a href="https://github.com/Phyks/Emails_SMS_Free_Mobile_API">ce script</a> qui va vous permettre de vous connecter à vos boîtes IMAP.</p>
  389. <p>Troisième étape, éditer le script pour correspondre à vos besoins. Tous les paramètres à modifier sont entre des commentaires <code># EDIT BELOW ACCORDING TO YOUR NEEDS</code> et <code># YOU SHOULD NOT HAVE TO EDIT BELOW</code>. Il vous faudra ajouter vos serveurs IMAP (serveur, login et mot de passe, et boîte à utiliser (par-défaut, INBOX)). Vous pouvez ajouter autant de serveurs que vous voulez en dupliquant les dictionnaires au sein de la liste <code>imap_servers</code>. Il vous faudra également éditer votre login pour l'API (<code>IDENT</code>, identifiant de connexion au compte) et la clé d'API à utiliser (<code>PASS</code>).</p>
  390. <p><em>Note</em>: L'URL ne devrait pas avoir besoin d'être modifiée, et <code>save_path</code> est le fichier JSON utilisé pour stocker les identifiants des emails relevés (et uniquement les identifiants), pour ne pas renvoyer la même notification plusieurs fois.</p>
  391. <p>Finalement, il ne reste plus qu'à mettre ce script sur un de vos serveurs (ou une machine allumée suffisamment souvent), et à le lancer <em>via</em> une <code>crontask</code>, par exemple <code>*/15 * * * * python3 ./mails_sms_free.py &gt; .mails_sms_free.log</code> pour relever vos emails toutes les 15 minutes.</p>
  392. <p><em>Note</em> : J'utilise ce script depuis une journée sans problèmes, mais il est sûrement imparfait. N'hésitez pas à <a href="https://phyks.me/contact.html">me signaler</a> (ou <em>via</em> les <em>issues</em> Github) d'éventuels problèmes rencontrés. </p>
  393. <footer>
  394. <p class="tags">Tags : <a href="http://phyks.me/tags/Dev.html">Dev</a>, <a href="http://phyks.me/tags/Phyks.html">Phyks</a></p></footer>
  395. </div>]]></content:encoded>
  396. <pubDate>Wed, 30 Jul 2014 12:00:00 -0000</pubDate>
  397. <category>Dev</category>
  398. <category>Phyks</category>
  399. <author>webmaster@phyks.me (Phyks)</author>
  400. </item>
  401. <item>
  402. <title>Diaspora*, c'est quand même pas pour tout le monde</title>
  403. <link>http://phyks.me/2014/07/diaspora_pas_pour_tout_monde.html</link>
  404. <guid isPermaLink="true">http://phyks.me/2014/07/diaspora_pas_pour_tout_monde.html</guid>
  405. <description>Ça faisait quelques mois que je disais que j'allais m'héberger une instance de Diaspora* (un pod comme ça s'appelle…</description>
  406. <content:encoded><![CDATA[<div class="article">
  407. <header></header>
  408. <!--
  409. @author=Phyks
  410. @date=29072014-2251
  411. @title=Diaspora*, c'est quand même pas pour tout le monde
  412. @tags=Libre
  413. -->
  414. <p>Ça faisait quelques mois que je disais que j'allais m'héberger une instance de <a href="ihttps://diasporafoundation.org/">Diaspora*</a> (un <em>pod</em> comme ça s'appelle). Finalement, sous la pression de <a href="http://tomcanac.com/">tmos</a> j'ai cédé et j'ai fini par m'occuper de ça ce weekend. Du coup, il est temps de faire un petit retour sur l'installation.</p>
  415. <p><em>Note :</em> Je ne m'attarderai pas sur l'historique et le but du projet (TLDR; un réseau social décentralisé et opensource), <a href="http://blog-libre.org/tag/diaspora">d'autres</a> l'ont déjà fait, ni sur l'utilisation, car je débarque et n'ai pas encore appréhendé la bête. C'est donc juste un retour sur l'installation, l'accessibilité de Diaspora* au plus grand nombre, et les premiers pas. De plus, je n'ai pas de commentaires sur ce blog statique, donc n'hésitez pas à <a href="http://phyks.me/contact.html">me contacter</a> pour en discuter.</p>
  416. <p>Il y a peu, <a href="http://maniatux.fr/index.php?article473/diaspora-c-est-pas-pour-moi">Maniatux</a> écrivait « Diaspora, c'est pas pour moi ». J'y suis, j'ai réussi à l'installer, mais je serai bien tenté de dire « Diaspora*, c'est pas pour tout le monde » voire même « Diaspora*, si tu n'es pas geek barbu libriste, mieux vaut passer ton chemin » (pour l'instant, j'espère). Retour sur les principaux points.</p>
  417. <h2>S'auto-héberger</h2>
  418. <p>Forcément, on parle de réseau social décentralisé, libre et on soulève plusieurs problématiques de vie privée avec les grands réseaux sociaux actuels (Twitter, Facebook, …). Donc si on passe sur Diaspora*, ce n'est pas a priori pour aller sur un pod pré-existant, et retomber dans un silo.</p>
  419. <p>Attention, je ne dis pas que c'est le mal absolu que d'aller sur un pod hébergé par quelqu'un d'autre, loin de là. On a une certaine qualité de service garantie et les principaux pods français (<a href="http://diaspora-fr.org/">diaspora-fr.org</a>, <a href="https://framasphere.org">FramaSphère</a>, …) sont aux mains d'association auxquelles je fais infiniment plus confiance qu'aux gros du web. Mais tant qu'à être présent sur ce réseau, et si on en a la possibilité, autant s'héberger soi-même. Comme j'héberge déjà mon compte Jabber et plusieurs autres services que j'utilise, autant essayer de continuer dans la décentralisation et héberger son propre <em>pod</em>.</p>
  420. <p>La majeure partie des commentaires dans la suite sera donc liée à cet auto-hébergement. Si vous êtes sur un pod hébergé par quelqu'un d'autre, vous ne les rencontrerez sûrement jamais mais ils sont à mon avis très importants pour un projet qui promeut la décentralisation.</p>
  421. <h2>Ruby, mon ami…</h2>
  422. <p>Diaspora a fait le choix d'utiliser Ruby, et non PHP qui est un langage très standard, déjà largement utilisé par <a href="http://wordpress.org">Wordpress</a> et tous les autres grands CMS. La plupart des utilisateurs a l'habitude de ces scripts et sait les installer facilement : une base de données créée avec PHPMyAdmin, un copier/coller avec un FTP ou SCP et éventuellement un petit <em>vhost</em> et ça marche. Faire le choix d'un langage « exotique », c'est se priver d'office d'un nombre conséquent d'utilisateurs, qui ne pourront pas l'installer facilement (ne serait-ce que parce qu'ils n'ont qu'un hébergement web et pas un serveur dédié).</p>
  423. <p>Ce choix est très certainement techniquement justifié (PHP est décrié par beaucoup), mais le fait est que Ruby, c'est compliqué à utiliser pour un utilisateur moyen. Il faut installer la bonne version, les bonnes <em>gems</em>, avoir les bons droits etc. Heureusement, Diaspora* utilise RVM qui simplifie grandement l'installation… quand ça fonctionne (j'y reviens un peu plus bas). Enfin, RVM simplifie l'installation, mais la rend d'autant plus obscure : on enchaîne les commandes listées sur le wiki, sans vraiment savoir ce qu'elles font et on passe un temps important à les décrypter pour comprendre ce qu'il va se passer. Dans tous les cas, Node.JS et Python sont déjà largement utilisés (avec des problèmes similaires cependant), les utiliser aurait déjà pu faciliter l'accès et augmenter la documentation disponible.</p>
  424. <p><em>Note :</em> Diaspora* utilise aussi Node.JS, mais « caché » derrière du Ruby. On est donc surtout confronté aux problèmes avec Ruby.</p>
  425. <p>Enfin, toutes ces technologies (Node.JS / Python / Ruby / …) ne s'interfacent pas directement avec Apache. Là où pour servir un script PHP, il faut tout au plus un <em>vhost</em>, il faut ici charger tout un tas de modules spécifiques pour Apache et servir <em>via</em> <em>mod_proxy</em> l'instance de Diaspora*. Chance, le <em>vhost</em> disponible sur le wiki fonctionne directement, mais je ne doute pas que les nombreuses instructions avancées utilisées décourageront bon nombre d'utilisateurs de comprendre ce que fait réellement ce <em>vhost</em> (ce qui est fort dommage).</p>
  426. <p>C'est donc à mon avis un gros point faible du projet (et je rejoins donc Maniatux), que de reposer sur Ruby, qui est un langage quand même assez exotique, qui empêchera les possesseurs d'un hébergement web seul de l'installer chez eux. Qui plus est quand d'autres technos comme Node.JS et Python sont disponibles, et avec beaucoup plus d'utilisateurs pour aider sur les problèmes généraux et non spécifiques à Diaspora*.</p>
  427. <h2>Des technos (trop ?) modernes</h2>
  428. <p>Diaspora* utilise Ruby, mais ce n'est pas la seule technologie moderne utilisée. On retrouve toutes les technos qui ont le vent en poupe : Node.JS, Boostrap, SASS, YAML, redis… Du coup, à chaque techno, une installation de paquets supplémentaires (redis par exemple), et un frein à la customisation (Bootstrap / SASS par exemple).</p>
  429. <p>Heureusement, les dépôts Debian sont bien fournis, et on peut désormais utiliser des paquets tout prêts pour redis et nodejs. Ça rajoute une étape à l'installation, et élimine définitivement les possesseurs de mutualisés, mais ça n'est pas la partie la plus compliquée.</p>
  430. <p>Les fichiers de configuration YAML sont très bien commentés et lisibles, c'est pratique. Par contre, l'utilisation de SASS oblige à connaître un minimum le fonctionnement de cet outil, et à compiler à chaque fois sa feuille de style. Je ne sais pas si les fonctions avancées de SASS simplifient grandement les feuilles de styles, mais la <em>bidouillabilité</em> en prend un coup =(.</p>
  431. <h2>Une documentation… minimale</h2>
  432. <p>Sur la documentation, rien à redire. La <a href="https://wiki.diasporafoundation.org/Installation/Debian/Wheezy?db=mysql&amp;mode=production">page de documentation</a> pour Debian Wheezy est complète.</p>
  433. <p>Par contre, la documentation est minimale. Comprenez bien qu'elle est complète donc contient toutes les commandes nécessaires pour s'en sortir et installer Diaspora*, mais ne contient rien de plus. Que faire après l'installation ? Quelques vagues liens sont disponibles en fin de page, mais il faudra se lancer dans l'exploration de son instance (quelques infos sur la façon de fermer son instance aux inscriptions, quelques informations pour faire ses premiers pas auraient été super). Un problème en marge de l'installation, une configuration un peu exotique ? Il faudra vous débrouiller par vous-même.</p>
  434. <p>Et se débrouiller par soi-même, c'est justement ça le problème. La doc sur RVM est assez minime, les chans IRC sont déserts (ou plus exactement il y a du monde, mais aucune activité visible)… (Merci au passage à <a href="https://github.com/Flaburgan">Flaburgan</a> qui a été un des seuls à répondre :)</p>
  435. <p>En particulier, j'ai eu des problèmes avec RVM. Je n'avais pas <span class="monospace">sudo</span> disponible sur mon serveur, et selon la documentation, je devais lancer <span class="monospace">rvm autolibs read-only</span>. Mais cette commande me retournait un magnifique <span class="monospace">rvm_debug: command not found</span>, quoi que je fasse et bien que tous les fichiers nécessaires aient été sourcés par bash (visiblement, il y avait un problème à ce niveau quand même). Du coup, je cherche cette erreur dans <del>Google</del> mon moteur de recherche favori, et je ne trouve qu'une <em>issue</em> vieille de 6 mois et corrigée. Je reteste plusieurs fois, en suivant scrupuleusement la <a href="https://rvm.io/development/">doc de RVM</a> (cette fois) et non celle de Diaspora* des fois qu'elle ne soit pas à jour. Rien à faire, toujours la même erreur. Je décide donc d'aller voir sur IRC, sur <span class="monospace">#diaspora</span> et <span class="monospace">#rvm</span>, aucune activité en 2 jours… Finalement, j'ai réussi à m'en sortir en bidouillant avec un <span class="monospace">export -f rvm_debug</span> et j'ai réussi à installer Diaspora*, mais je ne sais toujours pas ce qu'il se passait…</p>
  436. <h2>Gourmand</h2>
  437. <p>Quand on lit les pré-requis dans le <a href="https://wiki.diasporafoundation.org/Installation/Debian/Wheezy?db=mysql&amp;mode=production">wiki</a>, on trouve qu'il faut au minimum 512Mo de RAM (et 1Go de swap) et un CPU multi-cœur. Ces pré-requis sont à destination des gens souhaitant héberger un <em>pod</em> de taille moyenne. Étant le seul utilisateur de mon pod, Diaspora* consommera sûrement beaucoup moins de ressources, à voir. Sinon, ça veut dire que Diaspora* ne pourra pas tourner sur un Raspberry Pi (par exemple), ce qui peut être dommage quand on voit que Cyrille Borne <a href="http://blog-libre.org/post/2014/07/21/installer-owncloud-en-5-minutes-sur-un-raspberry-pi-et-autres">installe un petit serveur XMPP sur son Raspi</a> et qu'une instance de Diaspora aurait pu le rejoindre pour faire un Raspberry Pi social qui contrôle notre identité sur les réseaux.</p>
  438. <h2>Premiers pas</h2>
  439. <p>On retrouve les principaux éléments des réseaux sociaux traditionnels. L'interface m'a un peu rappelé (feu) <a href="http://status.net/">StatusNet</a> (ou plus exactement son successeur, <a href="http://pump.io/">pump.io</a>, la faute à Bootstrap je suppose). On arrive sur une vue des derniers posts très classique et on peut poster directement.</p>
  440. <p>Diaspora* met l'accent sur le contrôle de ses données, à travers les aspects (équivalents aux cercles de Google+ je pense). Du coup, chaque post peut être à destination d'un cercle différent, et ce comportement est un peu déroutant au début. En particulier, les posts sont privés par défaut, et il faut commencer à taper son message puis dérouler une liste déroulante pour modifier les aspects qui pourront voir ce post. À noter également qu'une fois un post écrit, son aspect ne peut être modifié.</p>
  441. <h2>Petite déception dans les fonctions de base</h2>
  442. <p>Diaspora* met l'accent sur le contrôle des données. Pourtant, je n'ai pas vu de moyen très simple d'exporter ses données (mais je ne doute pas que ça existe), mais surtout pour les importer. On ne peut donc pas migrer son instance sur un autre pod. C'est dommage, j'aurais bien testé sur un pod hébergé avant de passer chez moi =(.</p>
  443. <p><strong>EDIT </strong> Autre truc un peu énervant. Quand on cherche un utilisateur, le moindre espace en trop dans le champ de recherche empêche la recherche de s'exécuter correctement.</p>
  444. <h2>Quelques points supplémentaires</h2>
  445. <ul>
  446. <li>J'ai essayé d'ajouter quelques contacts. Aucun problème avec ceux hébergés sur <a href="http://diaspora-fr.org/">diaspora-fr.org</a>, mais j'ai eu beaucoup plus de mal à ajouter un autre utilisateur qui s'auto-hébergeait. On n'a pas encore élucidé ce qu'il se passait, mais il semblerait que je me sois même fait bloqué par portsentry lorsque j'ai essayé de l'ajouter…</li>
  447. <li>Bien penser à cocher la case « permettre à tous de chercher votre profil » pour que les autres puissent vous ajouter.</li>
  448. <li><strong>EDIT :</strong> Je découvre petit à petit Diaspora* et pour l'instant, je regrette quand même un peu le manque de fédération. C'est décentralisé, mais c'est un gros amas de petits ilots centralisés (les <em>pods</em>). Par exemple, les contacts ne sont pas fédérés et ne s'affichent qu'au sein d'un même <em>pod</em>.</li>
  449. <li><strong>EDIT </strong> Les mentions sont bien pratiques, comme sur Twitter, mais ne sont pas utilisables dans des commentaires…</li>
  450. </ul>
  451. <footer>
  452. <p class="tags">Tags : <a href="http://phyks.me/tags/Libre.html">Libre</a></p></footer>
  453. </div>]]></content:encoded>
  454. <pubDate>Tue, 29 Jul 2014 19:51:00 -0000</pubDate>
  455. <category>Libre</category>
  456. <author>webmaster@phyks.me (Phyks)</author>
  457. </item>
  458. <item>
  459. <title>Lister des corrections en ligne</title>
  460. <link>http://phyks.me/2014/07/inline_diff.html</link>
  461. <guid isPermaLink="true">http://phyks.me/2014/07/inline_diff.html</guid>
  462. <description>Il m'arrive souvent de corriger des documents textes et de devoir noter facilement les fautes d'orthograph…</description>
  463. <content:encoded><![CDATA[<div class="article">
  464. <header></header>
  465. <!--
  466. @author=Phyks
  467. @date=24072014-2235
  468. @title=Lister des corrections en ligne
  469. @tags=Dev
  470. -->
  471. <p>Il m'arrive souvent de corriger des documents textes et de devoir noter facilement les fautes d'orthographe. Idéalement:</p>
  472. <ul>
  473. <li>Un humain devrait être capable de le lire sans difficultés.</li>
  474. <li>Une machine devrait pouvoir le <em>parser</em> facilement pour effectuer la correction elle-même.</li>
  475. <li>Le correcteur devrait avoir un minimum de mots à recopier.</li>
  476. </ul>
  477. <p>Une solution est de corriger directement le document, puis de faire un <em>diff</em>. Ça marche, mais ce n'est pas des plus pratiques (on n'a pas forcément <em>diff</em> partout par exemple, ou encore le texte source n'est pas disponible pour du Markdown ou du LaTeX) et c'est quand même pas le plus lisible pour le destinataire. Pour résoudre ce problème, on peut utiliser <a href="etherpad.org"><em>etherpad</em></a> (dont une instance est disponible chez <a href="http://framapad.org/">FramaSoft</a> pour ceux qui ne veulent pas auto-héberger) par exemple, qui va garder les corrections en couleur et ce sera donc très lisible.</p>
  478. <p>Ceci dit, j'utilise une autre solution, qui ne nécessite qu'un éditeur de texte brut, et qui, un peu comme Markdown, est facilement lisible par un humain ou une machine. Je ne suis sûrement pas le seul à l'utiliser, et ça n'a sûrement pas grand chose d'extraordinaire, mais si jamais ça peut servir à d'autres personnes… (au moins à ceux à qui j'envoie mes corrections dans ce format ^^)</p>
  479. <p>Le plus simple est de partir d'un exemple. Considérons le texte suivant:</p>
  480. <blockquote>Cec est un text de démonstratin. Comme vous pouvez aisément le constater il y a quelques lettres manquntes et quelqueslettres en troap ou des mauvaises lettres. C'est donc un bon exiample.</blockquote>
  481. <p>Évidemment, le texte corrigé est:</p>
  482. <blockquote>Ceci est un texte de démonstration. Comme vous pouvez le constater aisément il y a quelques lettres manquantes et quelques lettres en trop ou des mauvaises lettres. C'est donc un bon exemple.</blockquote>
  483. <p>Pour ce texte, ma proposition de correction serait:</p>
  484. <pre>Cec(+i)
  485. text(+e)
  486. démonstrati(+o)n
  487. manqu(+a)ntes
  488. quelques(+ )lettres
  489. tro(-a)p
  490. ex(-ia+e)mple</pre>
  491. <p>Avec cette méthode, la correction est très courte, facilement lisible et très vite écrite. Détaillons-la un peu plus.</p>
  492. <p>Premier constat: il est très rare d'avoir des parenthèses au sein d'un mot. Et quand il y a des parenthèses, il n'y a jamais (en français correctement typographié, sauf erreur de ma part) un + ou un - qui suit une parenthèse ouvrante. On va donc englober dans des parenthèses nos corrections, directement au sein du mot. Au sein d'une parenthèse, on commencera toujours par le symbole - suivi de la lettre (ou des lettres consécutives) à retirer, s'il y a lieu. Puis viendra le symbole + suivi des lettres à insérer à la place dans le mot.</p>
  493. <p>Quand il manque une lettre dans le mot, elle est dans le champ de vision au sein de la parenthèse quand on lit le mot, et la lecture du mot est facilitée, tout en voyant immédiatement qu'il y a une faute à cet endroit. Quand il y a une lettre en trop, il suffit de ne pas lire la parenthèse pour avoir le mot complet bien écrit. Quand il y a eu une substitution, les lettres à insérer sont après le +, et les lettres à retirer sont après le -. La lecture d'un tel <em>diff</em> est donc très facile.</p>
  494. <p>Pour un ordinateur, il est également très facile de lire un tel diff. Le code serait le suivant:</p>
  495. <ul>
  496. <li>Découper le texte en mots.</li>
  497. <li>Pour chaque mot, regarder s'il y a un (ou plusieurs) groupe(s) de parenthèses contenant des + et des -, au format précédent.</li>
  498. <li>Pour chaque mot qui en contient, retirer les caractères suivant le - et ajouter ceux suivant le +.</li>
  499. </ul>
  500. <p>Une implémentation basique (et mal codée) en Python qui traite un mot serait :</p>
  501. <code><pre>def inline_diff(word):
  502. index = word.find('(-')
  503. if index == -1:
  504. index = word.find('(+')
  505. if index == -1:
  506. return word
  507. index_end = word.find(')', index)
  508. if index_end == -1:
  509. return False
  510. output = word[:index]
  511. action = 'add'
  512. for i in range(index, index_end):
  513. if word[i] == '(':
  514. continue
  515. elif word[i] == '-':
  516. action = 'remove'
  517. elif word[i] == '+':
  518. action = 'add'
  519. else:
  520. if action == 'remove':
  521. continue
  522. else:
  523. output += word[i]
  524. output += word[index_end+1:]
  525. return inline_diff(output)</pre></code>
  526. <p>Il reste à traiter le cas d'un diff complet. Plutôt que de fournir le texte complet, on peut se contenter de fournir une liste des corrections, comme la liste précédente, par ordre d'apparition dans le texte. Avec très peu de précautions nécessaires, une telle liste pourrait être traitée directement par un ordinateur pour apporter les corrections.</p>
  527. <p><strong>Mise à jour :</strong> Enfin, n'oublions pas d'aborder quelques limitations de ce système:</p>
  528. <ul>
  529. <li>Si le texte possède deux orthographes d'un mot, il faut prendre des précautions pour la correction. En particulier, il faut rappeler le mot à corriger autant de fois qu'il y a de corrections à faire, et on ne peut pas faire d'option <em>greedy</em>. Cependant, ceci devrait déjà être le cas si vous utilisez la méthode décrite précédemment.</li>
  530. <li>Dans le cas du texte suivant:
  531. <blockquote>Il existe des fois où la technique peut être utilisée moyennant quelques précautions. Dans cet exemple, les technique précédentes ne fonctionneront pas sans précautions.</blockquote>
  532. Si on utilise <span class="monospace">technique(+s)</span>, c'est la première qui sera remplacée. Il faut donc étendre cette méthode pour traiter un contexte suffisant pour effectuer le remplacement sans ambiguïtés. Le <em>diff</em> adéquat serait:
  533. <pre>les technique(+s)</pre>.</li>
  534. <li>On ne peut pas déplacer de mots facilement avec cette méthode. Plus exactement, c'est possible mais n'est pas optimal. Considérons le texte suivant:
  535. <blockquote>Dans ce texte, les sont mots inversés.</blockquote>
  536. Moyennant une implémentation un peu plus large de l'algorithme, on pourrait utiliser la méthode précédente comme ceci, pour corriger cette phrase:
  537. <pre>les (-sont) mots (+sont)</pre>
  538. car rien n'interdit à un mot d'être entièrement supprimé ou ajouté.
  539. </li></ul>
  540. <footer>
  541. <p class="tags">Tags : <a href="http://phyks.me/tags/Dev.html">Dev</a></p></footer>
  542. </div>]]></content:encoded>
  543. <pubDate>Thu, 24 Jul 2014 19:35:00 -0000</pubDate>
  544. <category>Dev</category>
  545. <author>webmaster@phyks.me (Phyks)</author>
  546. </item>
  547. <item>
  548. <title>Pourquoi la GPL n'est pas (si) libre</title>
  549. <link>http://phyks.me/2014/07/pourquoi_gpl_pas_libre.html</link>
  550. <guid isPermaLink="true">http://phyks.me/2014/07/pourquoi_gpl_pas_libre.html</guid>
  551. <description>Cet article est une traduction (dont je ne garantis pas la qualité :) de cet article (en anglais). Je n'ai pas réussi à contacter l'auteur, et si celui-ci passe par là et souhaite le retrait de la traduction, je la retirera…</description>
  552. <content:encoded><![CDATA[<div class="article">
  553. <header></header>
  554. <!--
  555. @author=Phyks
  556. @date=16072014-1900
  557. @title=Pourquoi la GPL n'est pas (si) libre
  558. @tags=Libre
  559. -->
  560. <p>Cet article est une traduction (dont je ne garantis pas la qualité :) de <a href="http://noordering.wordpress.com/2009/01/20/why-the-gpl-is-not-free/">cet article (en anglais)</a>. Je n'ai pas réussi à contacter l'auteur, et si celui-ci passe par là et souhaite le retrait de la traduction, je la retirerai.</p>
  561. <p>Cet article résume bien le problème que me pose la clause de redistribution sous une licence compatible, qui complique bien souvent l'utilisation de la licence (notamment car ce qu'on peut réellement faire avec un code sous GPL n'est pas toujours très clair et intuitif). C'est une des raisons pour laquelle je privilégie généralement une licence plus permissive, comme la <a href="https://tldrlegal.com/license/mit-license">MIT</a>. La dernière partie sur l'échec de la GPL est moins convaincante, et peut être même un peu tirée par les cheveux, mais elle fait partie de l'article donc je la laisse.</p>
  562. <p>À partir de maintenant et dans toute la suite, « je » désigne donc l'auteur de l'article précédent.</p>
  563. <h1>Pourquoi la GPL n'est pas libre</h1>
  564. <h2>Introduction</h2>
  565. <p>La <a href="http://www.fsf.org/">Free Software Foundation (FSF)</a> présente la <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> comme un défenseur idéal de vos libertés. On nous dit que la GPL est au cœur de la défense de quatre libertés :</p>
  566. <ol>
  567. <li>La liberté de faire tourner le programme, pour n'importe quelle raison (liberté 0).</li>
  568. <li>La liberté d'étudier comment le programme fonctionne, et de l'adapter à vos besoins (liberté 1). L'accès au code source est une condition préliminaire à cette liberté.</li>
  569. <li>La liberté de redistribuer des copies pour que vous puissiez facilement aider vos voisins (liberté 2).</li>
  570. <li>La liberté d'améliorer le programme et de diffuser les améliorations (et les versions modifiées en général) au public, pour que la communauté entière en bénéficie (liberté 3). L'accès au code source est une condition préliminaire à cette liberté.</li>
  571. </ol>
  572. <p><a href="http://www.gnu.org/philosophy/free-sw.html">« Qu'est-ce que le logiciel libre ? », sur le site de la GNU</a></p>
  573. <p>J'affirme cependant que la GPL ne nous donne pas de liberté, mais juste différentes restrictions. J'affirme de plus qu'elle ne nous donne pas toutes les libertés précédentes. Dans cet article, je défend que la GPL est intrinsèquement imparfaite quand il s'agit de libérer les logiciels.</p>
  574. <h2>Qu'est-ce que j'ai écrit ?</h2>
  575. <p>Permettez moi d'ouvrir une parenthèse avant de commencer. Je voudrais présenter un sujet lié qui est au cœur de mon argumentation, et qui est la question de savoir combien de code exactement vous avez écrit. Imaginons un scénario typique : vous êtes l'auteur d'une bibliothèque libre et <em>open source</em>. Le but de cette bibliothèque n'importe pas particulièrement, donc disons qu'elle sert à chiffrer des <em>widgets</em>. Vous mettez tout votre talent dans cette bibliothèque, et elle devient stable et très complète. Le diagramme représente le projet à ce moment :</p>
  576. <p style="text-align:center;"><a href="http://phyks.me/2014/07/gpl_pas_libre_1.png"><img alt="Votre projet, initialement." src="http://phyks.me/2014/07/gpl_pas_libre_1.png"/></a><br/>
  577. Vous êtes fier de votre projet.</p>
  578. <p>Supposons donc maintennt qu'une tierce partie prenne votre code et construise quelque chose par dessus. On pourrait le représenter comme ceci :</p>
  579. <p style="text-align:center;"><a href="http://phyks.me/2014/07/gpl_pas_libre_2.png"><img alt="Des ajouts à votre projet." src="http://phyks.me/2014/07/gpl_pas_libre_2.png"/></a><br/>
  580. Un important et un petit ajout à votre projet.</p>
  581. <p>Ce qui est important ici, c'est de réaliser que la quantité de code que vous avez écrite ne change pas. Même si l'ajout de la tierce partie consiste seulement en une jolie interface graphique pour votre bibliothèque, la quantité de code que vous avez écrite n'a pas augmenté, ni diminué.</p>
  582. <h2>Ce que vous couvrez avec une licence</h2>
  583. <p>Ok, posons donc maintenant la question : quelle est la pertinence de tout ceci ? Ça nous a aidé à clarifier ce que vous couvrez exactement par la licence lorsque vous appliquez une licence GPL à votre code. Vous couvrez <em>votre</em> code, et seulement votre code. Et pourtant, la GPL restreint la licence des travaux dérivés. Notons ici que les travaux dérivés sont <em>intégralement</em> le travail de quelqu'un d'autre.</p>
  584. <p>L'argument le plus courant que j'ai entendu pour favoriser la GPL est qu'avec une licence plus faible (disons <a href="http://www.opensource.org/licenses/bsd-license.php">BSD</a>), une tierce partie peut prendre votre code, l'étendre, et fermer l'accès aux sources. Réfléchissons donc à ce que cela signifie. Pour fermer l'accès à votre code, ils auraient du le prendre, retirer toutes les sources en accès libre pour ce code, et ensuite le distribuer à nouveau en <em>closed source</em>. Mais cela n'a aucun sens. Vous distribuez toujours votre code source sous une licence libre et <em>open source</em>, donc en quoi l'ont-ils rendu <em>closed source</em> ? Ils ne l'ont pas fait : <em>votre code</em> est toujours <em>open source</em>. Donc, qu'ont-ils rendu <em>closed source</em> ? Et bien, la réponse est « leur code », et <em>seulement</em> leur code est <em>closed source</em>, et c'est très bien : ils sont dans leur droit d'appliquer la licence de leur choix à leur code.</p>
  585. <p>Donc la conclusion est qu'une entreprise peut venir, prendre libWidgetCrypt et proposer un petit <em>wrapper</em> autour, et commencer à faire d'énormes profits en vendant le résultat $10,000. Oui, c'est possible, mais c'est aussi un scénario assez improbable. Si tout ce qu'ils ont fait a été d'écrire un petit <em>wrapper</em>, alors vous, ou quelqu'un d'autre dans la communauté <em>open source</em> est parfaitement capable de réaliser un tel <em>wrapper</em> en un rien de temps. Et alors, tout ce qu'il vous reste à faire est de casser les prix et d'ajouter un bon gros morceau de liberté.</p>
  586. <p>Le scénario le plus probable, cependant, est qu'une entreprise arrive, prenne libWidgetCrypt et produise un gros morceau de code supplémentaire, qui utilise juste votre bibliothèque dans sa base. Alors, cette entreprise va vendre <em>son</em> code, et <em>ses extensions</em> pour un montant élevé, et ils ont parfaitement le droit de le faire. Après tout, c'est leur code.</p>
  587. <p>Croyez le ou non, ce scénario est encore un scénario bénéfique pour vous. Cette entreprise est susceptible de trouver des bugs dans libWidgetCrypt, et de les corriger. De mon expérience de ce genre de choses, ils contribuent et vous font parvenir leurs correctifs plus souvent qu'on le pense, même si rien ne les y oblige ! Oui, il arrive qu'ils corrigent la bibliothèque et s'enfuient avec les correctifs, mais encore une fois, ils ont écrit les correctifs, ils ont le droit de le faire !</p>
  588. <h2>Là où la GPL rate</h2>
  589. <p>Je suis entré dans beaucoup de détails sur ce que vous mettez sous GPL quand vous appliquez une licence GPL à votre code, mais je n'ai pas encore parlé de ce que j'avais annoncé au début de cet article. Je ne vous ai pas dit pourquoi la GPL n'est pas une licence libre. Pour cela, je vais me concentrer sur la dernière liberté qu'elle affirme offrir : « La liberté d'améliorer le programme, et de diffuser les améliorations (et les versions modifiées en général) au public, pour que la communauté entière en bénéficie (liberté 3). ». Supposons que j'ai une entreprise, et que je crée un produit à distribuer. J'aimerais utiliser votre bibliothèque dans mon programme, j'aimerais même améliorer votre bibliothèque, et diffuser les améliorations publiquement, pour que l'intégralité de la communauté en bénéficie. Malheureusement, je dois finir par vendre un produit, donc j'aimerais garder le cœur de mon projet <em>closed source</em>. Malheureusement, la GPL proscrit ce genre de choses.</p>
  590. <p>Nous avons donc un bon citoyen, une entreprise qui veut diffuser leurs correctifs à la bibliothèque, et pourtant la GPL leur interdit de le faire. Elle ne leur donne aucune liberté ! À la place, la GPL est un ensemble de restrictions.</p>
  591. <p>Il se peut que vous trouviez que l'ensemble de restrictions que la GPL offre est plus moralement acceptable que les licences <em>closed source</em> traditionnelles, mais ce n'est <em>pas</em> une licence libre. Elle ne donne pas de liberté, elle donne différentes restrictions.</p>
  592. <h2>Conclusions</h2>
  593. <p>La GPL n'est pas une licence libre, en ce qu'elle restreint les libertés aux seules personnes qu'elle juge moralement acceptables. Il y a souvent des gens qui ne tombent pas dans cette case « moralement acceptable », mais qui ont pourtant de très bonnes intentions. La GPL est donc trop restrictive pour beaucoup de projets. À la place, c'est souvent une bonne idée d'utiliser une véritable licence <em>FOSS</em>, comme la licence BSD par exemple. En faisant cela, vous ne vous rendrez pas vulnérable pour des entreprises qui voudraient passer magiquement votre code en <em>closed source</em>, car vous continuerez à le distribuer. Il se peut qu'ils passent en <em>closed source</em> un petit ajout à votre code et essayent de le vendre pour des sommes astronomiques. Cependant, dans ce cas, vous pouvez aussi reproduire le même changement mineur, et le donner entièrement librement à la communauté.</p>
  594. <footer>
  595. <p class="tags">Tags : <a href="http://phyks.me/tags/Libre.html">Libre</a></p></footer>
  596. </div>]]></content:encoded>
  597. <pubDate>Wed, 16 Jul 2014 16:00:00 -0000</pubDate>
  598. <category>Libre</category>
  599. <author>webmaster@phyks.me (Phyks)</author>
  600. </item>
  601. <item>
  602. <title>Documenter son code PHP avec doxygen</title>
  603. <link>http://phyks.me/2014/07/doxygen_php.html</link>
  604. <guid isPermaLink="true">http://phyks.me/2014/07/doxygen_php.html</guid>
  605. <description>Je cherchais hier un moyen de générer une belle doc PHP, à partir de mes fichiers sources. Je connaissais quelques outils de la sorte (OcamlDoc, Sphinx pour Python, JavaDoc et…</description>
  606. <content:encoded><![CDATA[<div class="article">
  607. <header></header>
  608. <!--
  609. @author=Phyks
  610. @date=16072014-1520
  611. @title=Documenter son code PHP avec doxygen
  612. @tags=Web, Dev
  613. -->
  614. <p>Je cherchais hier un moyen de générer une belle doc PHP, à partir de mes fichiers sources. Je connaissais quelques outils de la sorte (OcamlDoc, Sphinx pour Python, JavaDoc etc.) mais je n'avais jamais regardé ça en détails.</p>
  615. <p>Du coup, je suis tombé sur <a href="http://www.stack.nl/~dimitri/doxygen/">Doxygen</a>, qui supporte une très grande variété de langages, est utilisé par beaucoup de scripts (dont des très gros comme Drupal) et était largement suffisant pour mes besoins. Il mange vos sources et génère de <a href="http://maniacbug.github.com/RF24/classRF24.html"><del>belles documentations</del></a> des pages de doc lisibles, en HTML, LaTeX, CHM et autres.</p>
  616. <p>J'ai pas trouvé de guides ultra rapides pour démarrer (ok, j'ai pas vraiment cherché non plus) donc je liste ici les 3 commandes de base, pour avoir une doc en 5 minutes chrono.</p>
  617. <p>Pour commencer, il faut faire <span class="monospace">doxygen -g .doxygen</span> dans le répertoire du projet pour générer un fichier de configuration (option <span class="monospace">-g</span>) nommé <span class="monospace">.doxygen</span>. Voici quelques paramètres utiles à modifier:</p>
  618. <ul>
  619. <li><span class="monospace">PROJECT_NAME</span>, mettre le nom de votre projet.</li>
  620. <li>Je voulais générer uniquement une doc HTML, et tout mettre dans un dossier doc. J'ai donc mis <span class="monospace">OUTPUT_DIRECTORY</span> à <span class="monospace">"doc/"</span>, puis <span class="monospace">HTML_OUTPUT</span> à <span class="monospace">.</span> (pour que la doc HTML aille dans <span class="monospace">doc/</span>) et enfin <span class="monospace">GENERATE_LATEX</span> à <span class="monospace">NO</span> pour ne pas générer de doc en LaTeX.</li>
  621. <li>Enfin, je voulais traiter tous les fichiers de mon projet, donc j'ai mis l'option <span class="monospace">RECURSIVE</span> à <span class="monospace">YES</span>.</li>
  622. </ul>
  623. <p>Une fois tout ceci fait, il faut que vos commentaires soient au bon format pour que doxygen les lise. Un exemple est disponible <a href="https://raw.githubusercontent.com/Phyks/Freeder/master/inc/functions.php">ici</a>.</p>
  624. <p>En gros, il faut à chaque fois redoubler les commentaires <span class="monospace">/** … */</span> pour que doxygen les <em>parse</em>. Les premières lignes de texte dans chaque cas sont un petit paragraphe descriptif. Il est possible d'ajouter un plus long paragraphe après avoir sauté une ligne. Doxygen utilise ensuite des tags <span class="monospace">@quelquechose</span> pour noter les paramètres, les valeurs de retours, les copyrights etc.</p>
  625. <p><strong>Important</strong>, ne pas oublier de dire à doxygen d'utiliser le fichier courant avec un <span class="monospace">@file</span> dans le commentaire global du fichier.</p>
  626. <p>Une fois tous vos fichiers <em>taggés</em> correctement, lancer <span class="monospace">doxygen .doxygen</span> depuis la racine de votre projet pour générer la doc. Vous obtiendrez une belle documentation <a href="https://freederteam.github.io/Freeder/doc/files.html">comme ça</a> (ok, il y a encore du boulot sur celle-ci…).</p>
  627. <footer>
  628. <p class="tags">Tags : <a href="http://phyks.me/tags/Web.html">Web</a>, <a href="http://phyks.me/tags/Dev.html">Dev</a></p></footer>
  629. </div>]]></content:encoded>
  630. <pubDate>Wed, 16 Jul 2014 12:20:00 -0000</pubDate>
  631. <category>Web</category>
  632. <category>Dev</category>
  633. <author>webmaster@phyks.me (Phyks)</author>
  634. </item>
  635. <item>
  636. <title>Specific Vim config per Git repository</title>
  637. <link>http://phyks.me/2014/07/specific_vim_config_git.html</link>
  638. <guid isPermaLink="true">http://phyks.me/2014/07/specific_vim_config_git.html</guid>
  639. <description>I was looking for a way to add custom vim options on a per-repo basis. The standard way I saw for now, was adding some comments to change the Vim config on a per-file basi…</description>
  640. <content:encoded><![CDATA[<div class="article">
  641. <header></header>
  642. <!--
  643. @author=Phyks
  644. @date=15072014-2220
  645. @title=Specific Vim config per Git repository
  646. @tags=Linux, Vim
  647. -->
  648. <p>I was looking for a way to add custom vim options on a per-repo basis. The standard way I saw for now, was adding some comments to change the Vim config on a per-file basis. There were some alternatives which were working for any project folder (and not only git repos) but they were only working if you start Vim from the root of the project, or they were exploring the tree from local folder up to root (and needed a plugin). None of them were satisfactory.</p>
  649. <p>When I edit a file and need specific Vim configuration, it is usually inside a git repo. So, it is easy to know what is the root folder, and I just wanted to search for a <span class="monospace">Vimrc</span> file in this folder. No complicated tree searching, working from anywhere inside the repo, no per-file specific configuration.</p>
  650. <p>First of all, the magic command I used to find the git root folder is <span class="monospace">git rev-parse --show-top-level</span>.</p>
  651. <p>Then, all I had to do is wrap it correctly in my <span class="monospace">.vimrc</span>:</p>
  652. <code>
  653. <pre>" Git specific configuration
  654. let git_path = system("git rev-parse --show-toplevel 2&gt;/dev/null")
  655. let git_vimrc = substitute(git_path, '\n', '', '') . "/.vimrc"
  656. if !empty(glob(git_vimrc))
  657. exec ":source " . git_vimrc
  658. endif
  659. </pre>
  660. </code>
  661. <p>This small code, added at the end of your <span class="monospace">.vimrc</span> will just look for a <span class="monospace">.vimrc</span> at the root the git repository and source it if possible. That's exactly what I wanted :)</p>
  662. <footer>
  663. <p class="tags">Tags : <a href="http://phyks.me/tags/Linux.html">Linux</a>, <a href="http://phyks.me/tags/Vim.html">Vim</a></p></footer>
  664. </div>]]></content:encoded>
  665. <pubDate>Tue, 15 Jul 2014 19:20:00 -0000</pubDate>
  666. <category>Linux</category>
  667. <category>Vim</category>
  668. <author>webmaster@phyks.me (Phyks)</author>
  669. </item>
  670. <item>
  671. <title>Quick and dirty benchmark of RSS/ATOM parsing libs</title>
  672. <link>http://phyks.me/2014/07/benchmark_rss.html</link>
  673. <guid isPermaLink="true">http://phyks.me/2014/07/benchmark_rss.html</guid>
  674. <description>EDIT: I just realized that the PHP function microtime does not return what I expected. This does not change much the results (to compare the solutions) but change the unit…</description>
  675. <content:encoded><![CDATA[<div class="article">
  676. <header></header>
  677. <!--
  678. @author=Phyks
  679. @date=10072014-1725
  680. @title=Quick and dirty benchmark of RSS/ATOM parsing libs
  681. @tags=Dev, Web
  682. -->
  683. <p><strong>EDIT:</strong> I just realized that the PHP function <span class="monospace">microtime</span> does not return what I expected. This does not change much the results (to compare the solutions) but change the units. I update the results accordingly.</p>
  684. <p>As I wrote in a <a href="http://phyks.me/2014/07/lecteur_rss_ideal.html">previous article</a>. I am working on a rss reader that could fit my needs. For this purpose, I am currently trying to see which way is the best way to parse RSS and ATOM feeds in PHP.</p>
  685. <p>I searched on the web for benchmarks, but I could only find old benchmarks, for old version of the libs and weird stuff (like parsing directly the feed with regex). So, I did a quick and dirty benchmark (and this is the reason why this article is in english :).</p>
  686. <h2>Which lib is the best one to parse RSS and ATOM feeds ?</h2>
  687. <p>I searched on the web for the available solutions. I found three main solutions (ordered from the most lightweight one to the less lightweight one):</p>
  688. <ul>
  689. <li><a href="https://github.com/broncowdd/feed2array">feed2array</a>, a lib by <a href="http://warriordudimanche.net/">Bronco</a> which is basically a wrapper around SimpleXML and is used by <a href="http://lehollandaisvolant.net/">timo</a> in his RSS reader implemented in <a href="https://github.com/timovn/blogotext">blogotext</a>. So it is tested on a quite wide range of feeds and should be considered fully working.</li>
  690. <li><a href="http://lastrss.oslab.net/">lastRSS</a>, a dedicated lib written in PHP</li>
  691. <li><a href="http://simplepie.org">SimplePie</a>, the well known lib, very complete, able to handle a wide range of feeds, correctly <strong>and</strong> incorrectly formatted, but very heavy.</li>
  692. </ul>
  693. <p>My goal was just to do a quick benchmark, so it is complete dirty and may not be very precise, but I did not need more. I did not test extensively all the available libs, especially all the wrappers around SimpleXML as the one I found was sufficient, and is basic enough to reflect a general result.</p>
  694. <p>My test lies on six RSS and ATOM feeds (both of them, to be sure that the lib worked on them) with a total of 75 articles. I parse them with the corresponding lib, and I do not display anything but the total time to parse them. I do not mind the ability of the lib to handle specially malformed feeds as these should not exist and parsing them may encourage their use. So, I am just interested in the time needed to parse these 6 feeds.</p>
  695. <p>The three libs parsed all of them successfully. I ran the test on my laptop, which can be considered almost 100% idle.</p>
  696. <p>The results are:</p>
  697. <table>
  698. <tr>
  699. <td>feed2array (and similar basic simpleXML based solution)</td>
  700. <td>about 40ms</td>
  701. </tr>
  702. <tr>
  703. <td>lastRss</td>
  704. <td>about 120ms and I got some mistakes</td>
  705. </tr>
  706. <tr>
  707. <td>SimplePie</td>
  708. <td>about 280ms</td>
  709. </tr>
  710. </table>
  711. <p>So, for my personnal case, I would simply say “the simpler the better” and go for feed2array that works perfectly on the feeds I want to use and is way faster than the overkill libraries. Very often I read that SimplePie was heavy and slow (despite their advertisement as “super fast”) and it seems to be confirmed by my results.</p>
  712. <p>In conclusion, however these results are just to be considered as orders of magnitude, and not precise measurements, I would say that you should avoid any complicated and overkill library unless you really need some of the advanced features it has. Your script will be way faster (up to 5 times faster or so according to these results).</p>
  713. <p><em>Note:</em> I only focused on these three libraries as it appears that they are the three main libraries available for this purpose (except for feed2array for which there are plenty of similar scripts). I wanted only scripts under a fully open source license, which eliminated some of the others. The only notable ones that I could have taken into account (I think) are the feed library from Zend, but I did not want to search for a way to get only the relevant functions from Zend, and the newly integrated PHP extensions such as XSLT. However, these PHP extensions are not widely available, and not built-in at all, so they may not be available on most of the shared hostings.</p>
  714. <h2>Store in a database / files or parse it each time ?</h2>
  715. <p>Next question I had was how do this time compare with retrieving infos from a database. For this purpose, I compared three times:</p>
  716. <ul>
  717. <li>time to parse the feeds using feed2array, which is about 40ms, as found before.</li>
  718. <li>time to load the arrays representing the feeds from serialized and gzipped files, which is about 8ms.</li>
  719. <li>time to load 75 elements (id, description, guid, link and pubDate) from a sqlite database, not optimized at all, which is about 2ms.</li>
  720. </ul>
  721. <p>As we could expect, it is longer to parse the feeds than to load them from a storage. So, it is definitely not a good idea to parse them at each page generation. Plus RSS format is not practical at all to do search and complex queries.</p>
  722. <p>The legit solutions are then to use flat files or a database. The difference between the two times is not so large, considering that files are gzipped and that I actually stored a bit more information in the file than in the table.</p>
  723. <p>However, there is not much optimization to do with files, whereas there are many ways to improve my results with a database. For instance, I used a basic sqlite table, without any potential optimization. But I could have used a more robust solution. If performances are really a concern, I could even use a temporary database, stored in RAM, to store the feeds elements. If this table is lost, that is not a big deal, as I will only have to do a refresh to get them back.</p>
  724. <p>Finally, one of the major problems with SQLite seems to be that it may be slow to write and completely locks the database when writing inside. But, this is also the case for flat files.</p>
  725. <p>In conclusion, I would say that the best solution appears to be SQLite with PDO. Actually, the use of PDO will enable to change the database very easily, and SQLite might be as good (if not better) as flat files.</p>
  726. <p><em>Note:</em> I put all my code and the test rss feeds in a zip archive available <a href="https://pub.phyks.me/benchmark_rss.zip">here</a>.</p>
  727. <footer>
  728. <p class="tags">Tags : <a href="http://phyks.me/tags/Dev.html">Dev</a>, <a href="http://phyks.me/tags/Web.html">Web</a></p></footer>
  729. </div>]]></content:encoded>
  730. <pubDate>Thu, 10 Jul 2014 14:25:00 -0000</pubDate>
  731. <category>Dev</category>
  732. <category>Web</category>
  733. <author>webmaster@phyks.me (Phyks)</author>
  734. </item>
  735. <item>
  736. <title>Mon lecteur RSS idéal</title>
  737. <link>http://phyks.me/2014/07/lecteur_rss_ideal.html</link>
  738. <guid isPermaLink="true">http://phyks.me/2014/07/lecteur_rss_ideal.html</guid>
  739. <description>EDIT : J'ai repris quelque peu le commentaire de FreshRSS, après discussion avec son auteur. J'avais raté certaines options en particulie…</description>
  740. <content:encoded><![CDATA[<div class="article">
  741. <header></header>
  742. <!--
  743. @author=Phyks
  744. @date=10072014-1724
  745. @title=Mon lecteur RSS idéal
  746. @tags=Web, Libre, Autohébergement
  747. -->
  748. <p><strong>EDIT :</strong> J'ai repris quelque peu le commentaire de FreshRSS, après discussion avec son auteur. J'avais raté certaines options en particulier.</p>
  749. <p><strong>EDIT 2:</strong> Suite à quelques retours sur cet article, je tiens à préciser que la première partie de l'article (« Panorama de ce qui existe ») est volontairement courte et caricaturale. C'est une compilation caricaturale de réflexions que j'ai entendues, et je ne m'étends volontairement pas dessus, pour ne pas allourdir inutilement cet article qui vise d'abord à présenter les points qui me semblent importants pour mon lecteur de flux RSS idéal.</p>
  750. <p><em>Attention, cet article est un bon pavé et il est sûrement plein de répétitions… :)</em></p>
  751. <p>Sam&amp;Max ont écrit récemment sur <a href="http://sametmax.com/pourquoi-sametmax-com-utilise-wordpress/">leur moteur idéal</a>. Le moteur de blog est un réel problème, et j'adhérerais immédiatement à un moteur de blog qui satisfasse leurs critères (mais bon, pour l'instant ma solution maison patchée de partout fonctionne pas trop mal :). En revanche, un autre point mérite une bonne réflexion et pourrait être grandement amélioré et modernisé : le lecteur RSS.</p>
  752. <p>J'utilise actuellement <a href="https://github.com/ldleman/Leed">Leed</a> sur mon serveur. J'en suis globalement satisfait, mais certains points m'agacent et ne sont pas résolus, au fil des versions. Pourtant, après avoir fait le tour des solutions existantes, c'est la solution la plus fonctionnelle que j'ai trouvée… Je profite donc de ce billet pour dresser un bilan de ce que j'ai vu passer sur les lecteurs RSS et ce que je voudrais trouver dans mon lecteur RSS idéal.</p>
  753. <h2>Panorama de ce qui existe</h2>
  754. <p>Tout d'abord, sebsauvage a fait il y a quelques temps un <a href="http://sebsauvage.net/rhaa/index.php?2013/03/15/17/15/39-arretez-de-pleurer-google-reader-hebergez-un-lecteur-rss-chez-vous">petit tour d'horizon des solutions de lecteurs RSS à héberger</a>. Je vais faire court, au risque de m'attirer les critiques :</p>
  755. <dl>
  756. <dt>Leed</dt>
  757. <dd>On attend le support du multi-utilisateur depuis un moment, il utilise <span class="monospace">mysql_</span> qui est déprécié, base MySQL obligatoire, quand même assez lourd, une licence non libre (CC BY SA NC), des développeurs principaux indisponibles (le <a href="http://leed.idleman.fr/">wiki</a> est globalement HS pour l'instant), un thème de base très moche, pas si simple à installer pour Mme Michu, des thèmes qui sont quand même limités, et <a href="https://github.com/ldleman/Leed/issues/391">bloqués par le dépôt principal</a>…</dd>
  758. <dt>KrISS Feed</dt>
  759. <dd>C'est moche, pas fonctionnel. Je ne me suis pas attardé sur le reste, qui semble assez standard.</dd>
  760. <dt>FreshRSS</dt>
  761. <dd>Il peut gérer beaucoup d'articles (100k annoncés sur le <a href="http://freshrss.org/">site</a>). C'est pas très bô (beau / ergonomique / efficace) non plus, trop compact (notamment sur smartphone, quand on a des gros doigts :), et les infos importantes ne sont pas mises en valeur (à mon avis, les flux sont les éléments principaux, à mettre en valeur ; sur FRSS, mon œil est beaucoup plus attiré par les dossiers et les boutons). C'est aussi compliqué à installer (base MySQL, même si c'est pas si compliqué, Cron manuel, instructions dans le README que ne lit pas Mme Michu), et cela risque de bloquer Mme Michu… Ses avantages par contre : il supporte très bien la charge, et l'intégration de Mozilla Persona est originale. Il a aussi de nombreuses possibilités, pour peu qu'on fouille un peu les menus de configuration.</dd>
  762. <dt>Aeres</dt>
  763. <dd>Site HS, mais ça a l'air très moche aussi.</dd>
  764. <dt>Miniflux</dt>
  765. <dd>Seul concurrent sérieux, à la vue du site. De très bonnes idées, comme le <em>full content</em> et la suppression des trackers à la volée, mais quand on ouvre la page de démo, c'est moche… et <strong>inutilisable</strong> ce qui est vraiment dommage pour un script qui est hébergé contre paiement. C'est minimaliste, trop minimaliste. Les liens pour marquer comme lus, non lus, supprimer etc sont invisibles, le texte de l'article non sélectionné est illisible, surtout sur un mobile en plein soleil, il n'y a aucun support de plugins, les raccourcis claviers sont complètement dissociés du contrôle à la souris et il me semble assez lourd quand on charge de nombreux articles.</dd>
  766. <dt>selfoss</dt>
  767. <dd>Ça commence bien, le site est beau et les <em>screenshots</em> donnent envie, mais qu'en est-il vraiment ? Déjà, c'est <strong>compliqué</strong> : l'installation est compliquée, la configuration se fait dans un fichier <span class="monospace">config.ini</span>, il n'y a pas de démo disponible, et quand on finit par l'installer pour le voir en action, on se rend compte que ce n'est quand même pas très utilisable.</dd>
  768. <dt>RSS Lounge</dt>
  769. <dd>Connu pour sa lourdeur, il fait tout (ou presque, il ne fait pas encore le café), on passe.</dd>
  770. <dt>cartulary</dt>
  771. <dd>C'est compliqué, le README est paumatoire, alors qu'il n'y a vraiment aucune raison d'expliquer de façon si compliquée une installation somme toute assez basique.</dd>
  772. <dt>RSS Miner</dt>
  773. <dd><a href="http://www.rssminer.net/">Le site</a> ne s'affiche pas correctement chez moi, la barre de gauche cachant la moitié de la page et ne se fermant pas, je m'attends au pire et je n'ai pas regardé plus en détails.</dd>
  774. <dt>News Blur</dt>
  775. <dd>Il y a des idées, notamment le côté social. Mais c'est compliqué, et hors de portée de beaucoup de monde, car ça tourne sous Django, avec du MongoDB et du PostgreSQL. Je ne suis pas sûr que le côté social soit compatible entre plusieurs instances et utilise un réseau décentralisé pré-existant, qui permettrait de le plugger facilement avec Diaspora ou n'importe quel autre logiciel du genre, et évitant de multiplier les réseaux et les protocoles.</dd>
  776. <dt>Feed HQ</dt>
  777. <dd>Inscription obligatoire pour tester, c'est aussi du python + redis + postgresql + elasticsearch, donc on oublie pour Mme Michu.</dd>
  778. </dl>
  779. <h3>Que conclure de ce panorama ?</h3>
  780. <p>Quoi que je fasse, je reviens vers Leed. De nombreuses fonctionnalités sont annoncées depuis un moment, et j'attends qu'elles voient le jour, mais il reste le plus fonctionnel et celui qui colle le mieux avec mon lecteur RSS idéal, tout en restant loin de la perfection. Le reste est moche, complexe, lent, et même les solutions payantes (mais opensources) ne s'en sortent guère mieux. Je n'utilisais pas Google Reader, mais s'il était dans la tradition des outils Google (simple, fonctionnel et rapide), je n'ai pas (encore ?) trouvé de réelle alternative.</p>
  781. <p>Concernant Leed, la première étape est bien sûr de changer le thème par défaut (Marigolds) pour un meilleur thème. Le plus complet et maintenu actuellement est <a href="https://github.com/tmos/greeder">Greeder</a> de <a href="http://tomcanac.com/">tmos</a> (bien que <a href="http://rss.remitaines.fr/">Hot Beer</a> se défende, même si je n'adhère absolument pas au format <em>webzine</em>). tmos travaille sur un pack Leed + greeder et sur l'intégration de Leed dans <a href="https://yunohost.org/">Yunohost</a>, qui devrait lui redonner un peu de fraîcheur.</p>
  782. <h2>Mais du coup, c'est quoi mon lecteur RSS idéal ?</h2>
  783. <h3>Rapidité, simplicité, fonctionnalité</h3>
  784. <p>Je met à jour mon lecteur RSS toutes les heures, et j'y passe donc quasiment une fois par heure. Je ne veux pas passer dix minutes à chaque fois pour réussir à cliquer sur le bon bouton, ou pour attendre que la page soit chargée.</p>
  785. <p>Il faut donc qu'il soit beau, intuitif (pour ça, Leed + greeder remplit bien ce rôle), rapide et fonctionnel. Le but est aussi de lire des articles, pas de voir défiler des titres, donc il faut que les articles soient affichés en entier (mais personnalisables <em>via</em> une option pour satisfaire tout le monde), sans avoir besoin de cliquer trois fois sur chaque article pour le lire.</p>
  786. <p>Je le regarde de partout, et beaucoup sur mon portable, dans les transports. Or, bien souvent, il n'y a pas de réseau dans les transports, et je ne veux pas d'une <a href="http://standblog.org/blog/post/2014/06/29/Web-Entrepreneur-Conference-videos-disponibles">énième app quand du HTML5 peut le faire</a>. Du coup, un thème responsive, des actions tactiles (comme Greeder, en plus étendu) et une utilisation du <em>local storage</em> et le tour est joué :)</p>
  787. <p>Toutes ces fonctionnalités (et celles qui vont suivre) peuvent paraître en contradiction avec « être léger, rapide et fonctionnel », mais si le script est suffisamment compartimenté, on peut ne charger que ce qui sera utile à l'affichage et conserver un grand nombre de fonctionnalités avancées, sans alourdir nécessairement le script (sauf dans le cas où tout serait activé en même temps).</p>
  788. <h3>Extensibilité et customisation</h3>
  789. <p>On ne peut pas faire un logiciel parfait, qui satisfasse tout le monde. Plutôt que d'opter pour le minimalisme et se priver ainsi de fonctions avancées, un système de plugins bien pensé me paraît mieux. Celui de Leed est bien pour ça, même s'il manque un peu de documentation. Idéalement, il faudrait même que les plugins et thèmes existants pour un des lecteurs RSS les plus répandu actuellement soient compatibles (mais là, je rêve je pense :).</p>
  790. <p>Quelques idées de plugins cools en vrac :</p>
  791. <ul>
  792. <li>Recherche : très souvent je lis des articles, puis quelques jours plus tard je réalise que j'aurais du les garder de côté car j'en ai besoin. Sauf qu'à ce moment, je ne sais plus sur quel flux je l'ai lu, et c'est une galère de le retrouver. Un plugin de recherche sur l'agrégateur permet de résoudre ce problème.</li>
  793. <li>Une implémentation de <a href="https://github.com/sebsauvage/rss-bridge">rss-bridge</a> pour le côté user-friendly.</li>
  794. <li>Des plugins spécifiques par flux, pour afficher les conversations entre shaarli en tant que conversations par exemple.</li>
  795. <li>Annotation de texte en direct pour noter rapidement des idées, des corrections de typo etc.</li>
  796. </ul>
  797. <p>Pour le côté user friendly et l'adoption par Mme Michu, il faudrait aussi une liste de plugins « officiels » (c'est-à-dire respectant les guidelines et donc compatibles) simple, à la wordpress. Il suffirait alors d'envoyer l'archive dans l'interface admin pour l'installer automatiquement.</p>
  798. <p>Idéalement, il faudrait des coding guidelines strictes, qui manquent sur les projets actuels. Notamment sur la façon d'écrire un thème ou sur les balises à utiliser dans un thème, afin de garantir la cohérence de l'interface et la rapidité du script. Leed par exemple, a un dépôt <a href="https://github.com/ldleman/Leed-market">market</a> très hétérogène, et des thèmes qui n'ont pas de base commune rendant très difficile l'implémentation de nouveau code sur plusieurs thèmes. Pire, certains plugins doivent être adaptés pour chaque thème, ce qui est une perte de temps considérable.</p>
  799. <h3>Une gestion fine des flux</h3>
  800. <p>Une autre fonctionnalité qui me paraît importante est de pouvoir gérer finement les flux, c'est-à-dire pouvoir prioriser, classer, trier et filtrer des flux très facilement.</p>
  801. <p>Un premier point est la gestion des doublons. Très souvent, il arrive d'avoir des articles similaires, sur le même sujet, voire même des articles tout simplement identiques, si certains flux se recoupent. Le premier cas est difficile à trier et à filtrer (même si idéalement ces articles devraient pouvoir être regroupés ensemble), mais le deuxième est très simple à filtrer. Les doublons devraient donc être masqués et gérés comme un seul et même article.</p>
  802. <p>Un autre point important est la présence du multi-utilisateur. Cela permet ainsi de ne charger qu'une seule fois les liens communs à plusieurs comptes, et d'accélerer le rafraîchissement des liens ainsi que d'alléger la charge des serveurs. Je vois deux cas d'utilisation importants : pouvoir avoir une seule instance pour tout une famille, et pouvoir avoir différents comptes par activité (un compte pro et un compte perso par exemple).</p>
  803. <p>D'autres fonctionnalités sympathiques sont proposées par certains lecteurs RSS, notamment la gestion de la priorité des flux, pour prioriser certains flux.</p>
  804. <p>Je pense aussi qu'il y a moyen de faire des trucs très sympas avec les dossiers, qui sont bien trop rigides comme fonctionnement (et que je n'utilise pas personnellement). Sûrement un système de tags, ou un système flexible par mot-clé. Mais je n'ai pas encore d'idées précises à apporter pour cette réflexion. N'hésitez pas à partager les votres :)</p>
  805. <h3>Transparence et protection de la vie privée</h3>
  806. <p>Un des principaux avantages de s'auto-héberger est d'avoir les contraintes de transparence, de sécurité et de protection de la vie privée qu'on se fixe, au lieu d'être dépendant d'une solution tierce sur ces points.</p>
  807. <p>Un lecteur RSS idéal, et toujours dans l'optique de l'utilisation par le plus grand nombre, devrait :</p>
  808. <dl>
  809. <dt>afficher de manière claire les logs disponibles</dt>
  810. <dd>on ne devrait jamais devoir aller chercher une information dans un obscur fichier de log écrit dans le répertoire du script, ou pire, dans les logs Apache. Au contraire, ces informations (historique de connexions, historiques de mise à jour, …) devraient être disponibles dans l'interface directement, de façon claire et compréhensible en un clin d'œil.</dd>
  811. <dt>des statistiques claires</dt>
  812. <dd>de même, une fonctionnalité absente de nombreux lecteurs RSS et qui me semble pourtant plutôt basique est la possibilité de voir en un clin d'œil quels sont les flux fréquemment mis à jour, quels sont les flux les plus actifs, les moins actifs, etc., ceci afin de pouvoir très facilement trier ses flux et supprimer les flux morts. Il m'est arrivé plusieurs fois d'avoir un flux qui a changé d'adresse, ou qui était momentanément indisponible, et de mettre plusieurs jours à m'en rendre compte, faute d'affichage clair comme "attention, le flux XXX n'a pas été mis à jour depuis N jours, alors qu'il avait une fréquence habituelle de M articles / jour"</dd>
  813. <dt>régler finement les permissions</dt>
  814. <dd>S'auto-héberger, c'est aussi pouvoir régler finement les fonctions avancées de ses logiciels. J'utilise intensivement la vue anonyme de Leed, pour ne pas avoir à me connecter à chaque visite, et car je trouve ça pratique de pouvoir voir les flux RSS que les autres suivent, on découvre bien souvent de nouveaux flux top comme ça. Mais sur la plupart des lecteurs actuels, soit tout est public, soit tout est privé. Or je ne veux pas forcément que <strong>tous</strong> mes flux soit publics. En particulier, certains flux liés à des services que j'utilise (mon Owncloud, par exemple) ne devraient pas être publics.</dd>
  815. <dt>être compatible avec les autres outils libres à disposition</dt>
  816. <dd>Enfin, même si je souhaite beaucoup de fonctions dans mon lecteur RSS, je ne veux pas qu'il devient un monstre polycéphal qui fait tout. Le libre a cela de merveilleux qu'il existe une infinité de petits outils qui font une seule petite tâche, mais la font très bien. Pourquoi implémenter aussi une gestion des favoris, quand Owncloud le propose, quand shaarli marche du tonerre et est de surcroît très simple à installer, etc. Il faut donc au contraire prévoir d'être compatible avec ces autres outils, pour que le libre soit cohérent. En particulier, owncloud propose un flux RSS accessible après authentification (POST) des "activités" sur le compte. Pratique pour suivre des dossiers partagés. Mais très peu de (si ce n'est aucun) lecteur RSS disponible ne gère cette authentification =(.</dd>
  817. <dt>promouvoir la vie privée de l'utilisateur</dt>
  818. <dd>En utilisant son propre lecteur RSS auto-hébergé, on a un contrôle total sur nos flux, et on ne divulgue pas d'informations non contrôlées à un tiers (typiquement l'hébergeur du lecteur RSS, qui pourra alors nous cibler plus finement). J'aimerais pouvoir retrouver ça dans mon lecteur avec un filtrage des liens feedburner par défaut, pour supprimer ces redirections et les remplacer par des liens directs, ainsi qu'un filtrage des publicités dans les flux, un peu à la manière des <a href="https://github.com/ldleman/Leed-market">plugins</a> urlclean et adblock pour Leed. Il pourrait aussi cacher le referer lors de l'ouverture d'un lien externe, etc. Il y a énormément de possibilités de ce côté.</dd>
  819. </dl>
  820. <h3>Toujours garder l'ergonomie en tête</h3>
  821. <p>L'ergonomie est sûrement un des points faibles des lecteurs RSS disponibles actuellement (et du logiciel libre ?). Elle est bien souvent négligée, et cela prive bon nombre d'utilisateurs d'utiliser les scripts en question.</p>
  822. <p>Pourtant, il y a moyen de faire beaucoup de choses, notamment en usant (abusant ?) de JavaScript et des fonctionnalités récentes (transitions CSS, HTML5 etc). Du drag&amp;drop s'implémente facilement, et facilite grandement l'utilisation pour beaucoup d'utilisateurs. Décrémenter un compteur d'éléments non lus en JavaScript chaque fois qu'on marque un élément comme lu prend 3 lignes de JavaScript et pourtant cela n'a été implémenté que récemment dans <a href="https://github.com/tmos/greeder/commit/446a521d240db62bc8350f54b31148429afeddb7">Greeder</a> et dans le thème par défaut de Leed.</p>
  823. <p>De plus, j'ai besoin d'une application web pour ne pas dépendre de l'ordinateur (ou du téléphone) que j'utilise. Que je sois sur mon téléphone, mon ordinateur ou n'importe quel autre périphérique, je retrouve mes news dans le même état, sans synchronisation compliquée, et sans développer un logiciel différent par périphérique. Le web est vraiment magique pour ça. Mais ce n'est pas pour autant que je ne veux pas que cette <em>webapp</em> se rapproche le plus possible d'une application native (qui sont bien souvent des <em>wrappers</em> autour d'une interface web, sur mobile, de toutes façons). Ainsi, sur mon portable, je veux retrouver des actions tactiles, un stockage en <em>local storage</em> car je risque d'être déconnecté sans raison, et une interface utilisable pleinement sans jouer avec le zoom. Et sur mon ordinateur, je veux pouvoir bénéficier d'une navigation au clavier, avec des raccourcis claviers, et de fonctionnalités avancées telles que le rafraîchissment régulier ou <a href="https://github.com/tmos/greeder/issues/71">la notification</a>, afin de se rapprocher le plus possible d'une application (et peut être un jour tourner dans sa propre instance du navigateur, pour ressembler vraiment à une application ?).</p>
  824. <p>Côté interface, celle-ci doit faciliter la lecture en mettant l'accent sur le contenu et les actions importantes. Il y a aussi beaucoup de boutons qui ont une fonction peu claire dans les scripts que j'ai pu voir : double négation dans les questions qui nous fait répondre « oui » quand on voulait dire « non », pas de rappel du nom du dossier quand on veut marquer tout un dossier comme lu (ce qui nous fait nous demander si on a bien cliqué sur le bon bouton)… D'autre part, quand je qualifiais les interfaces de « moches » au début de cet article, c'était bien souvent que l'interface était peu claire / paumatoire / clicodrôme.</p>
  825. <p>La mode est au <em>scroll</em> infini. C'est bien pratique quand on a une connexion permanente, mais dès que la connexion coupe, qu'on recharge la page, et qu'on se retrouve tout en haut, c'est nettement moins drôle. Du coup, vive la pagination, en gardant une option pour le <em>scroll</em> infini, pour ceux qui l'aiment particulièrement. Par contre, si le <em>local storage</em> est très largement utilisé, le <em>scroll</em> infini peut s'envisager, car la perte de connexion ne bloquera pas la page.</p>
  826. <p>Enfin, un dernier point essentiel à mon avis est la possibilité de se connecter automatiquement et d'avoir un <em>bookmarklet</em> efficace pour ajouter des flux (idéalement, une intégration directe avec le module d'abonnement de Firefox :). Leed a un bon <em>bookmarklet</em> mais la connexion automatique n'est arrivée que récemment. Et attention sur ce point, <a href="https://github.com/sebsauvage/Shaarli">Shaarli</a> a une connexion automatique erratique, qui a tendance à ne pas passer chez certains hébergeurs.</p>
  827. <h3><del>Paraître</del>Être sérieux</h3>
  828. <p>Trop de scripts de ce genre ont aussi des traductions approximatives, <em>monkey patchée</em> ou bourrées de fautes. L'inernationalisation est importante de nos jours et ne doit pas être négligée, surtout qu'elle est désormais facilitée par les outils disponibles et qu'elle n'est pas si problématique si pensée depuis le début. Faire un test sur les nombres à afficher pour afficher l'accord si besoin n'est pas très long, et il est possible de faire une fonction à appeler pour le faire à chaque fois. Ce n'est pas grand chose, mais c'est plus propre, plus beau et plus tentant. Une bonne traduction, une bonne licence, un code en anglais et des <em>coding guidelines</em> motiveront plus les gens pour écrire du code et faire des contributions.</p>
  829. <p>Il faut aussi avoir une sortie régulière de versions, quitte à sortir des versions rapprochées. Si toutes les nouvelles fonctions sont regroupées dans une branche <span class="monospace">dev</span> et regroupées dans une version stable une fois par an, Mme Michu ne verra qu'une version par an, et se dira donc que le développement est lent, même si chaque version apporte énormément de nouveautés. Au contraire, un dépôt avec des commits réguliers est plus attirant car on se dit que le logiciel vit, qu'il est suivi et qu'on n'aura donc pas à attendre longtemps si on rencontre un problème avec. Personnellement, si je rencontre un problème bloquant avec un logiciel et que celui-ci n'est pas résolu rapidement (en quelques semaines tout au plus), que je le veuile ou non, j'oublie l'existence de ce logiciel, je trouve des alternatives, et je retombe dessus par hasard quelques mois plus tard.</p>
  830. <p>De même, on ne peut pas tout développer, et on ne peut pas tout réinventer. Du coup, il devient important de virer les fonctionnalités inutiles, ou qui font doublon avec d'autres programmes, pour ne pas réinventer la roue et se consacrer sur les points essentiels pour le script.</p>
  831. <h3>Et tout cela… pour tous</h3>
  832. <p>Comme j'ai déjà insisté pas mal dessus, je reprendrais juste brièvement quelques points dans cette partie. Mais pour rester dans l'érgonomique et le beau, un tel script devrait être facile à installer, à configurer et à utiliser, par tous.</p>
  833. <p>Ceci passe par une interface user friendly, utilisant pleinement les fonctionnalités offertes par les navigateurs aujourd'hui (drag&amp;drop, AJAX, …). Ceci passe aussi par l'internationalisation, la présence d'une vraie liste d'extensions, facilement utilisable, une doc claire et à jour et un fonctionnement identique (dans la mesure du possible) sur la plupart des hébergements disponibles.</p>
  834. <p>Du côté de la licence, un tel lecteur RSS devrait être sous une licence libre (dans le sens de logiciel libre), ce qui n'est malheureusement pas le cas de Leed aujourd'hui (sous licence CC-BY-NC-SA), qui a d'ailleurs une licence ambiguë, déconseilleé pour les codes sources (voir <a href="http://freear.org.uk/content/creative-commons-licenses-software-just-say-no">ici</a> ou <a href="http://wiki.creativecommons.org/Frequently_Asked_Questions#Can_I_use_a_Creative_Commons_license_for_software.3F">ici</a>) et complexe comme le montre <a href="http://www.framablog.org/index.php/post/2012/10/15/non-commercial-creative-commons">cet article chez Framasoft</a>, un comble pour une licence qui se veut simple et intuitive. :)</p>
  835. <p>Enfin, un des principaux points est sûrement de pouvoir mettre à jour les flux facilement, sans y penser et sans intervention. Actuellement, la plupart des lecteurs nécessitent une intervention de l'utilisateur pour ajouter une <em>crontask</em>. C'est compliqué, source de problèmes, d'erreurs en recopiant etc, et ça complique l'installation pour pas mal de monde. Il y a sûrement moyen de rendre cela plus facile aussi, en tout cas ça serait top si c'était le cas. <a href="http://owncloud.org/">Owncloud</a> par exemple propose de lancer les tâches par AJAX, webcron ou cron, sans configuration de la part de l'utilisateur.</p>
  836. <h2>Conclusion</h2>
  837. <p>Aucun lecteur RSS ne me satisfait pleinement, mais Leed me paraît le moins imparfait à l'heure actuelle. En prenant des briques à gauche, à droite, on réunit la plupart des fonctions qui me paraissent importantes, mais je pense qu'il y a encore moyen de faire beaucoup pour s'affranchir des modèles classiques et établis de lecteurs RSS et proposer quelque chose d'innovant, misant sur l'ergonomie et s'adressant au plus grand nombre.</p>
  838. <p>Je vais essayer de mettre ça en pratique, en gardant en tête les points que je juge le plus important : facilité d'utilisation, ergonomie, beau et performant. Je ferai sûrement quelques articles sur des points spécifiques que je croiserai. Si vous me lisez et que vous avez un hébergement mutualisé, n'hésitez pas à me donner des infos sur votre hébergement PHP (version de PHP, modules disponibles qui sont trouvables dans le phpinfo notamment) car je ne sais pas exactement quelles sont les installations typiques de PHP sur mutualisé.</p>
  839. <p>Enfin, beaucoup de fonctionnalités seraient implémentées très facilement en utilisant les technos à la mode, nodejs ou les solutions à base de python par exemple. Mais cela oblige à se priver du côté « facilement installable par tous » car ces solutions ne sont pas disponibles sur la plupart des hébergeurs mutualisés. Ça semble aussi être un des problèmes de <a href="https://diasporafoundation.org/">Diaspora*</a> par exemple, car j'entends régulièrement qu'<a href="http://maniatux.fr/index.php?article473/diaspora-c-est-pas-pour-moi">installer son pod est compliqué</a>, notamment car Diaspora* utilise Ruby, C'est vrai, et si c'est pour utiliser un pod public, proposé par la communauté, beaucoup d'utilisateurs ne voient pas de réelles différences par rapport à Facebook,</p>
  840. <footer>
  841. <p class="tags">Tags : <a href="http://phyks.me/tags/Web.html">Web</a>, <a href="http://phyks.me/tags/Libre.html">Libre</a>, <a href="http://phyks.me/tags/Autohébergement.html">Autohébergement</a></p></footer>
  842. </div>]]></content:encoded>
  843. <pubDate>Thu, 10 Jul 2014 14:24:00 -0000</pubDate>
  844. <category>Web</category>
  845. <category>Libre</category>
  846. <category>Autohébergement</category>
  847. <author>webmaster@phyks.me (Phyks)</author>
  848. </item>
  849. <item>
  850. <title>Quelques astuces pour Arduino</title>
  851. <link>http://phyks.me/2014/07/astuces_arduino.html</link>
  852. <guid isPermaLink="true">http://phyks.me/2014/07/astuces_arduino.html</guid>
  853. <description>Voici astuces en vrac pour Arduino que j'ai découvertes ces derniers jours, en codant pour CitizenWatt et en particulier pour le capteu…</description>
  854. <content:encoded><![CDATA[<div class="article">
  855. <header></header>
  856. <!--
  857. @author=Phyks
  858. @date=02072014-2215
  859. @title=Quelques astuces pour Arduino
  860. @tags=DIY, Électronique
  861. -->
  862. <p>Voici astuces en vrac pour Arduino que j'ai découvertes ces derniers jours, en codant pour <a href="http://citizenwatt.paris/">CitizenWatt</a> et en particulier pour le <a href="https://github.com/CitoyensCapteurs/CitizenWatt-sensor">capteur</a>.</p>
  863. <h2>Stocker des données en Flash</h2>
  864. <p>Il peut arriver d'avoir pas mal de données statiques dans un programme et donc d'arriver à court de RAM disponible (2ko sur un ATMega 328p / Arduino Uno). Et quand ça arrive, c'est le drame (typiquement, le Serial se mettait à faire n'importe quoi dans mon cas)…</p>
  865. <p>Par exemple, à chaque appel de <span class="monospace">Serial.println("Quelque chose");</span>, la chaîne de caractères <span class="monospace">"Quelque chose"</span> est chargée en RAM. Du coup, sur un code assez long, avec pas mal d'affichage verbeux sur la liaison série, on sature vite la RAM.</p>
  866. <p>Qu'à cela ne tienne, il est possible de stocker la chaîne dans la Flash et de la charger directement depuis la Flash. Avant, c'était compliqué, il fallait utiliser <span class="monospace">PROGMEM</span>, mais depuis la version 1.0 de l'IDE, il suffit d'entourer la chaîne de <span class="monospace">F()</span>, par exemple <span class="monospace">Serial.println(F("Quelque chose"));</span>. <a href="http://playground.arduino.cc/Learning/Memory">Source</a></p>
  867. <p>Et au passage, <a href="http://playground.arduino.cc/Code/AvailableMemory">un petit bout de code</a> pour savoir combien il reste de RAM disponible.</p>
  868. <h2>Les préférences de l'IDE</h2>
  869. <p>Je n'avais jamais été faire un tour dans les préférences de l'IDE non plus, principalement par flemme. Qu'à cela ne tienne, c'est désormais chose faite, et j'y ai croisé quelques options vraiment vitales.</p>
  870. <p>En particulier, <span class="monospace">Afficher les résultats détaillés pendant compilation</span> qui permettra d'avoir un <em>output</em> plus verbeux pendant la compilation.</p>
  871. <p>Mais la vraie révélation de cette soirée, c'est l'option <span class="monospace">Utiliser un éditeur externe</span>. Vous ne supportez plus l'éditeur Arduino et son indentation pourrie, ses fonctionnalités dignes de <span class="monospace">notepad</span> premier du nom et son non affichage des numéros de ligne (à part en bas dans un petit coin, inutilisable au possible pour débugger efficacement), cette option est faite pour vous ! En l'activant, Arduino ne lira plus le fichier. Vous pouvez l'éditer comme vous voulez dans un éditeur externe (Vim &lt;3) et au moment d'<em>uploader</em> le code, l'IDE Arduino ira relire le fichier, le compiler et l'<em>uploader</em>.</p>
  872. <footer>
  873. <p class="tags">Tags : <a href="http://phyks.me/tags/DIY.html">DIY</a>, <a href="http://phyks.me/tags/Électronique.html">Électronique</a></p></footer>
  874. </div>]]></content:encoded>
  875. <pubDate>Wed, 02 Jul 2014 19:15:00 -0000</pubDate>
  876. <category>DIY</category>
  877. <category>Électronique</category>
  878. <author>webmaster@phyks.me (Phyks)</author>
  879. </item>
  880. <item>
  881. <title>Viens faire mon hackathon avec plein de CC dedans</title>
  882. <link>http://phyks.me/2014/04/hackathon_cc.html</link>
  883. <guid isPermaLink="true">http://phyks.me/2014/04/hackathon_cc.html</guid>
  884. <description>J'ai reçu aujourd'hui une pub pour hack4france, un « hackathon 100% made in France ». On passera sur le hackathon made in France avec du bon anglais de partout (et oui, aussi surprenant que ça puisse paraître, hack4France, c'est pas du français, en bon français, ça donnerait « hack pour la France », tout de suite moins in), sur les récompenses et sur les APIs proposées pour regarder la FAQ et le règlement qui devraient faire hurler tout défenseur des licences libre…</description>
  885. <content:encoded><![CDATA[<div class="article">
  886. <header></header>
  887. <!--
  888. @author=Phyks
  889. @date=29042014-2050
  890. @title=Viens faire mon hackathon avec plein de CC dedans
  891. @tags=Libre
  892. -->
  893. <p>J'ai reçu aujourd'hui une pub pour <a href="http://www.hackate.am/fr/challenges/hack4france">hack4france</a>, un « hackathon 100% <em>made in France</em> ». On passera sur le hackathon <em>made in France</em> avec du bon anglais de partout (et oui, aussi surprenant que ça puisse paraître, <em>hack4France</em>, c'est pas du français, en bon français, ça donnerait « hack pour la France », tout de suite moins <em>in</em>), sur les récompenses et sur les APIs proposées pour regarder la FAQ et le règlement qui devraient faire hurler tout défenseur des licences libres. Malheureusement, c'est trop souvent comme ça avec ce genre de hackathons.</p>
  894. <p>Déjà, c'est quoi un <a href="https://en.wikipedia.org/wiki/Hackathon">hackathon</a> ? L'idée de base est de hacker pendant une journée, pour faire bien avancer un projet ou faire émerger de nouvelles idées. Maintenant, si on lit entre les lignes, le hackathon proposé est plutôt “trouvez-nous un projet innovant et sympa, qui va bien se vendre et en échange on vous donne quelques cadeaux”.</p>
  895. <p>Seul problème : le créateur du projet reste l'auteur et donc garde le copyright. Pas génial comme truc si on veut le reprendre, le modifier de notre côté et se faire plein d'argent avec. Pas de problèmes, on a un truc génial pour ça, la Creative Commons !</p>
  896. <p>Du coup, il est précisé dans le réglement (article 12) que tous les éléments produits (à l'exception du code lui-même) seront sous licence Creative Commons BY, ce qui fait qu'il sera très facile pour eux de le réutiliser, et que « le créateur garantit le Prestataire, et les Entreprises Partenaires contre tout trouble, action, réclamation, opposition, revendication et éviction quelconque provenance d’un tiers. ».</p>
  897. <p>Ok, donc on a un concours, on gagne des trucs et en plus mes créations graphiques (entre autres) sont sous Creative Commons. Malgré l'utilisation quelque peu vicieuse de la Creative Commons, c'est leur droit et le participant est au courant en lisant le réglement qu'il a accepté. À part un problème de morale, il n'y a pas grand chose à en dire. Certes, mais ça, c'est avant d'avoir vu <a href="http://www.hackate.am/fr/challenges/hack4france/pages/faq">la FAQ</a>.</p>
  898. <p>Notamment dans la partie “Que devient le résultat du hackathon ?”,</p>
  899. <blockquote>Vous restez l'entier propriétaire du prototype et de son code. Pour plus de précisions, nous vous invitons à lire le réglement du challenge.</blockquote>
  900. <p>Certes, on reste propriétaire du code car on ne peut céder ses droits moraux dans le droit français, mais on remarquera qu'on passe très étrangement sous silence que les productions seront sous licence Creative Commons. Pour plus de précisions, il faut aller se noyer dans le réglement et tomber sur l'article 12.</p>
  901. <p>Plus grave encore, à la question “Dois-je partager mon code ?”, il est répondu que ce n'est pas obligatoire. En effet, je ne <strong>dois</strong> pas partager mon code, rien ne m'oblige à le partager. Mais rien n'empêche le partage des autres éléments pour autant. Et il faut bien comprendre que tous les autres éléments <strong>seront</strong> partagés. Et un code n'est pas le plus dur à reproduire une fois qu'on a l'idée et les éléments graphiques.</p>
  902. <p>Tout ça sera déjà partagé entre les juges, et les entreprises qui financent le concours. Si une idée leur plait, pas de doutes qu'elles la récupèront et en feront quelque chose. Mais ensuite, grâce à la licence CC BY, il suffit que n'importe quel membre du jury veuille redistribuer, et il sera dans son droit pour le faire. Tout sauf le code sera alors partagé.</p>
  903. <p>Bref, une utilisation vicieuse des Creative Commons et une FAQ qui omet judicieusement certains éléments…</p>
  904. <p>P.S. : On remarquera qu'ils se sont d'ailleurs judicieusement limité à la CC BY, en excluant toute possible ND, NC ou SA qui aurait grandement réduit l'intérêt du dispositif.</p>
  905. <p>EDIT : Correction d'une erreur qui s'était glissée dans l'article. Le code n'est pas sous licence Creative Commons, mais tous les autres éléments le sont.</p>
  906. <footer>
  907. <p class="tags">Tags : <a href="http://phyks.me/tags/Libre.html">Libre</a></p></footer>
  908. </div>]]></content:encoded>
  909. <pubDate>Tue, 29 Apr 2014 17:50:00 -0000</pubDate>
  910. <category>Libre</category>
  911. <author>webmaster@phyks.me (Phyks)</author>
  912. </item>
  913. <item>
  914. <title>Élysée.fr… accessibilité et cloud souverain</title>
  915. <link>http://phyks.me/2014/04/elysee.html</link>
  916. <guid isPermaLink="true">http://phyks.me/2014/04/elysee.html</guid>
  917. <description>Vous avez sûrement déjà vu un
  918. site officiel sur l'IVG utiliser Google Analytics, ce qui n'est pas sans
  919. poser quelques problèmes d'anonymat et de confidentialité, un cloud souverain mais vous
  920. n'avez sûrement pas encore vu le site de
  921. l'Élysée (en tout cas, moi je ne l'avais jamais vu il y a encore quelques
  922. jours) !
  923. Mais hier, je suis tombé sur cet article
  924. sur le blog webatou qui reportait des
  925. popins sur le site de l'Élysée, comportement assez étonnant pour un site
  926. officiel, qui vante son
  927. accessibilité (mais non, il n'y a bien sûr aucun popin sur cette
  928. page…), qui fait appel à une
  929. société (dont on n'ose même pas imaginer la facture) pour améliorer son
  930. accessibilit…</description>
  931. <content:encoded><![CDATA[<div class="article">
  932. <header></header>
  933. <!--
  934. @author=Phyks
  935. @date=29042014-2030
  936. @title=Élysée.fr… accessibilité et cloud souverain
  937. @tags=Web
  938. -->
  939. <p>Vous avez sûrement déjà vu <a href="http://reflets.info/fic2014-ces-administrations-francaises-qui-livrent-ce-que-vous-avez-de-plus-intime-a-des-tiers-google-xiti/">un
  940. site officiel sur l'IVG utiliser Google Analytics</a>, ce qui n'est pas sans
  941. poser quelques problèmes d'anonymat et de confidentialité, un <a href="http://reflets.info/?s=cloud+souverain">cloud souverain</a> mais vous
  942. n'avez sûrement pas encore vu le <a href="http://www.elysee.fr/">site de
  943. l'Élysée</a> (en tout cas, moi je ne l'avais jamais vu il y a encore quelques
  944. jours) !</p>
  945. <p>Mais hier, je suis tombé sur <a href="http://blog.webatou.info/post/sur-twitter-les-popins">cet article</a>
  946. sur <a href="http://blog.webatou.info">le blog webatou</a> qui reportait des
  947. popins sur le site de l'Élysée, comportement assez étonnant pour un site
  948. officiel, qui <a href="http://www.elysee.fr/accessibilite/">vante son
  949. accessibilité</a> (mais non, il n'y a bien sûr aucun <em>popin</em> sur cette
  950. page…), qui fait appel à <a href="http://blog.temesis.com/post/2012/12/19/Elysee-site-plus-accessible-avec-temesis">une
  951. société</a> (dont on n'ose même pas imaginer la facture) pour améliorer son
  952. accessibilité. Ok, <a href="http://blog.barbayellow.com/2007/09/30/laccessibilite-selon-lelyseefr/">elle
  953. n'était pas parfaite</a>, mais c'était déjà ça.</p>
  954. <p>Mais alors, que leur a-t-il pris de mettre un énorme <em>popin</em> pour
  955. <q>les suivre sur Facebook</q> (sérieusement, la présidence est tellement en
  956. manque de reconnaissance, qu'il lui faut des <em>likes</em> sur Facebook ?).
  957. Pas de problèmes, je clos le popin. Prochain chargement, la même chose pour
  958. Twitter ! Je ferme encore, prochain rechargement, la même chose pour la
  959. newsletter. Je suis <strong>assez grand</strong> pour savoir où je veux vous
  960. suivre tout seul, pas besoin de <strong>3</strong> <em>popins</em> !</p>
  961. <p>Du coup, je me suis penché un peu plus sur le site, et je suis juste
  962. consterné… On passera sur l'enveloppe en haut de page qui n'a rien à voir avec
  963. un quelconque contact, mais permet juste de s'abonner à la newsletter, on
  964. passera sur les mêmes pages qui sont liées à N endroits différents sur le site,
  965. avec un texte différent à chaque fois, idéal pour perdre le visiteur (mais bon,
  966. c'est une <a href="http://lehollandaisvolant.net/?d=2014/03/04/14/09/35-pourquoi-les-sites-des-services-publics-sont-ils-tous-aussi-pourris">spécialité
  967. des services publics apparemment</a>)… Non, ce qui m'a inquiété, c'est
  968. l'origine du petit script JavaScript responsable du <em>popin</em>.</p>
  969. <p>Pas de problèmes, on recharge la page en activant la console de Firefox, et
  970. on découvre qu'il n'y a pas moins de 15 scripts différents chargés (totalisant
  971. un poids voisin de 900ko (oui oui, <strong>900ko</strong> soit trois fois plus
  972. que l'image la plus lourde de la page, mais #ToutVaBien), ce qui est finalement
  973. dans la moyenne des pages webs actuelles avec leur tendance à cracher du
  974. JavaScript à la pelle) dont <strong>un seul hébergé sur le serveur de
  975. l'élysée</strong>.</p>
  976. <p>Oui oui, vous avez bien lu, sur le site de l'Élysée, il y a
  977. <strong>14</strong> scripts (soit 93% des scripts) qui viennent d'un serveur
  978. externe (Facebook, google API, Twitter, Typekit et readspeaker). Et je ne parle
  979. que des javascripts, pas des images et des CSS (qui finalement sont presque
  980. tous chez l'Élysée pour le coup). Ça veut donc dire qu'au moins 4 grandes
  981. entreprises américaines peuvent inclure un peu ce qu'elles veulent sur la page
  982. de l'Élysée. Joli !</p>
  983. <p>Enfin, on notera que le seul contact que j'ai pu trouver pour l'équipe
  984. responsable du site de l'Élysée était une adresse postale à l'Élysée, pratique
  985. à l'heure où envoyer un e-mail n'a jamais été aussi simple et rapide.</p>
  986. <p>P.S. (disclaimer) : Pour tous ceux qui chercheront à relever tous les
  987. problèmes d'accessibilité sur mon blog, je sais qu'il est loin d'être parfait,
  988. et il faudra que je m'en occupe quand j'aurai 5 minutes. Sauf que dans un cas
  989. on parle d'un blog personnel, n'ayant aucune prétention particulière, et dans
  990. l'autre cas on parle d'un site <strong>institutionnel</strong> qui se prétend
  991. modèle d'accessibilité…</p>
  992. <footer>
  993. <p class="tags">Tags : <a href="http://phyks.me/tags/Web.html">Web</a></p></footer>
  994. </div>]]></content:encoded>
  995. <pubDate>Tue, 29 Apr 2014 17:30:00 -0000</pubDate>
  996. <category>Web</category>
  997. <author>webmaster@phyks.me (Phyks)</author>
  998. </item>
  999. <item>
  1000. <title>Utilisons des formats simples et arrêtons la multiplication des applications pour les transports ?</title>
  1001. <link>http://phyks.me/2014/04/app_transport.html</link>
  1002. <guid isPermaLink="true">http://phyks.me/2014/04/app_transport.html</guid>
  1003. <description>Cette dernière semaine, j'ai pris un vol easyjet, un vol airfrance, un train italien et un train françai…</description>
  1004. <content:encoded><![CDATA[<div class="article">
  1005. <header></header>
  1006. <!--
  1007. @author=Phyks
  1008. @date=26042014-2132
  1009. @title=Utilisons des formats simples et arrêtons la multiplication des applications pour les transports ?
  1010. @tags=Smartphone
  1011. -->
  1012. <p>Cette dernière semaine, j'ai pris un vol easyjet, un vol airfrance, un train italien et un train français. Cela fait donc 4 billets de transport que j'ai pris sur internet. Si je ne voulais pas les imprimer, je pouvais les utiliser directement sur mon smartphone, à condition d'utiliser l'application associée. Je ne sais pas comment fonctionne trenitalia et airfrance, mais pour la SNCF et easyjet, chacun oblige à installer son application.</p>
  1013. <p>J'ai donc le choix entre imprimer 4 billets inutilement (juste pour avoir un QRCode qui pourrait être facilement scanné sur mon smartphone) ou à devoir installer au moins deux applications : celle d'easyjet et celle de la SNCF.</p>
  1014. <p>Pourtant, ces applications font exactement la même chose que ce que je peux déjà faire sur mon téléphone : elles affichent un QRCode ! J'ai déjà un lecteur de fichiers PDF et la galerie d'images sur mon smartphone, alors, pourquoi devrais-je en installer deux autres ?!</p>
  1015. <p>Bref, il est vraiment dommage que chacun reste dans son coin, avec son application propriétaire, disponible uniquement sur le store officiel (et donc nécessitant un compte Google sur Android) et tout ça pour proposer une fonctionnalité qui existe déjà sur mon téléphone ?! Enfin, aujourd'hui, si tu n'as pas ton application attitrée qui vient encombrer l'écran d'accueil de l'utilisateur lambda, tu n'es rien… Tant pis, qu'on garde ces applications, mais qu'on laisse aussi les gens utiliser un format universel et leur smartphone comme ils l'entendent pour afficher le QRCode nécessaire ! Surtout que l'utilisateur a bien souvent l'e-mail avec la confirmation et le billet en PDF dans ses e-mails.</p>
  1016. <p>P.S. : Peut être que l'utilisation de l'application dédiée n'est pas nécessaire… Officieusement en tout cas. Mais sur le site de la SNCF (et d'easyjet), on ne parle que de deux possibilités : l'impression papier et l'utilisation de l'application dédiée, en spécifiant que le billet n'est pas valide pour toutes les autres utilisations.</p>
  1017. <p>EDIT : Apparemment, pour le contrôle à bord du train, tant qu'on peut présenter le code, éventuellement sur son smartphone, c'est bon. Par contre, ce n'est pas indiqué sur les conditions d'utilisation, et je ne sais pas si c'est officiel…</p>
  1018. <footer>
  1019. <p class="tags">Tags : <a href="http://phyks.me/tags/Smartphone.html">Smartphone</a></p></footer>
  1020. </div>]]></content:encoded>
  1021. <pubDate>Sat, 26 Apr 2014 18:32:00 -0000</pubDate>
  1022. <category>Smartphone</category>
  1023. <author>webmaster@phyks.me (Phyks)</author>
  1024. </item>
  1025. <item>
  1026. <title>Interruptions possibles de service dans les prochains jours</title>
  1027. <link>http://phyks.me/2014/04/out.html</link>
  1028. <guid isPermaLink="true">http://phyks.me/2014/04/out.html</guid>
  1029. <description>Je vais changer mon serveur kimsufi que j'ai depuis 1 an, pour un nouveau de la gamme 2013, largement plus puissant pour le même pri…</description>
  1030. <content:encoded><![CDATA[<div class="article">
  1031. <header></header>
  1032. <!--
  1033. @author=Phyks
  1034. @date=12042014-1630
  1035. @title=Interruptions possibles de service dans les prochains jours
  1036. @tags=Phyks
  1037. -->
  1038. <p>Je vais changer mon serveur kimsufi que j'ai depuis 1 an, pour un nouveau de la gamme 2013, largement plus puissant pour le même prix. Du coup, je vais tout transférer sur la nouvelle machine (mufasa.phyks.me) dans les prochains jours, et, me connaissant, je vais sûrement rater un truc :)</p>
  1039. <p>Du coup, il se peut que vous rencontriez quelques difficultés à accéder à mon site dans les prochains jours. J'éditerai cet article quand tout sera migré.</p>
  1040. <p>Update (13/04, 17h33) : Migration terminée. Tout s'est bien passé en fait, et je ne crois pas avoir eu d'interruption de service (à part <a href="http://git.phyks.me">git.phyks.me</a> pendant quelques heures).</p>
  1041. <footer>
  1042. <p class="tags">Tags : <a href="http://phyks.me/tags/Phyks.html">Phyks</a></p></footer>
  1043. </div>]]></content:encoded>
  1044. <pubDate>Sat, 12 Apr 2014 13:30:00 -0000</pubDate>
  1045. <category>Phyks</category>
  1046. <author>webmaster@phyks.me (Phyks)</author>
  1047. </item>
  1048. </channel>
  1049. </rss>