Changaco's blogChangacohttp://changaco.oy.lc/blog/Changaco's blogikiwiki2015-09-13T16:46:41ZGoodbye Gratipayhttp://changaco.oy.lc/blog/goodbye-gratipay/2015-09-13T16:46:41Z2015-04-17T11:15:51Z
<p>I have been Gratipay's <a href="https://github.com/gratipay/gratipay.com/graphs/contributors?from=2014-04-01&to=2015-04-15&type=c">top developer</a> for a year, but now the time
has come for me to leave the team.</p>
<h2 id="why">Why?</h2>
<p>A few days ago Gratipay's founder decided to start banning users from the site,
for reasons that are not acceptable to me.</p>
<p>To be clear, I don't care specifically about <a href="https://twitter.com/infinitechan">infinitechan</a> and <a href="https://twitter.com/rabite">rabite</a>
(the two users being kicked out), I had never even heard of them before joining
the Gratipay team, same as I hadn't heard of Shanley Kane before the so-called
<a href="http://geekfeminism.wikia.com/wiki/Gittip_crisis">"Gittip crisis"</a>.</p>
<h2 id="whatnow">What now?</h2>
<p>Leaving <a href="https://gratipay.com/Gratipay/members/">the Gratipay team</a> is greatly diminishing my income, as I was
receiving $110/week through it.</p>
<p>I don't plan to start a fork of Gratipay. I am currently <a href="https://github.com/Changaco/legi.py">working on French
open data</a>, then I'm not sure what I'll do. I may try to turn my idea
of a new programming language (a mix of Haskell and Python, to put it
simplistically) into something concrete (anyone wants to help with that?).</p>
<p>I will keep <a href="https://gratipay.com/Changaco/">my Gratipay account</a> open for now, but I am also
looking for other ways to fund my work.</p>
<p><strong><em>Edit:</strong> Gratipay <a href="https://medium.com/gratipay-blog/gratipay-2-0-2453d3c53077">has strayed even further away</a> from the original idea of Gittip, and I've received requests for an alternative, so I'm now working on <a href="http://liberapay.com/">Liberapay</a>.</em></p>
<h2 id="postscriptum">Post Scriptum</h2>
<p>Gratipay was not <a href="https://twitter.com/rabite/status/588377441078349824">messing</a> with Weev's account prior to this,
the credit card of the person who was giving to him simply stopped working,
which is a very common problem.</p>
<p>Gratipay <a href="https://gratipay.com/about/pricing">doesn't take a cut of payments</a>, so <a href="https://twitter.com/SecretGamerGrrl/status/588465222232383488">tweets like this</a>
are ridiculous.</p>
Parsing an indented tree in Haskellhttp://changaco.oy.lc/blog/parse-indented-tree/2012-06-04T17:49:16Z2012-06-04T17:49:16Z
<p>An example of how to parse an indented tree of data in Haskell using <a href="http://hackage.haskell.org/package/parsec">Parsec</a> and <a href="http://hackage.haskell.org/package/indents">indents</a>.</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">></span> <span class="kw">import</span> Control.Applicative
<span class="ot">></span> <span class="kw">import</span> Data.Char (isSpace)
<span class="ot">></span> <span class="kw">import</span> Data.Either.Utils (forceEither)
<span class="ot">></span> <span class="kw">import</span> Data.Monoid
<span class="ot">></span> <span class="kw">import</span> System.Environment (getArgs)
<span class="ot">></span> <span class="kw">import</span> Text.Parsec <span class="kw">hiding</span> (many, optional, (<|>))
<span class="ot">></span> <span class="kw">import</span> Text.Parsec.Indent</code></pre>
<p>A basic tree structure:</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">></span> <span class="kw">data</span> <span class="dt">Tree</span> <span class="fu">=</span> <span class="dt">Node</span> [<span class="dt">Tree</span>] <span class="fu">|</span> <span class="dt">Leaf</span> <span class="dt">String</span></code></pre>
<p>A simple serialization function to easily check the result of our parsing:</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">></span> serializeIndentedTree tree <span class="fu">=</span> <span class="fu">drop</span> <span class="dv">2</span> <span class="fu">$</span> s (<span class="fu">-</span><span class="dv">1</span>) tree
<span class="ot">></span> <span class="kw">where</span>
<span class="ot">></span> s i (<span class="dt">Node</span> children) <span class="fu">=</span> <span class="st">"\n"</span> <span class="fu"><></span> (<span class="fu">concat</span> <span class="fu">$</span> <span class="fu">replicate</span> i <span class="st">" "</span>) <span class="fu"><></span> (<span class="fu">concat</span> <span class="fu">$</span> <span class="fu">map</span> (s (i<span class="fu">+</span><span class="dv">1</span>)) children)
<span class="ot">></span> s _ (<span class="dt">Leaf</span> text) <span class="fu">=</span> text <span class="fu"><></span> <span class="st">" "</span></code></pre>
<p>Our main function and some glue:</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">></span> main <span class="fu">=</span> <span class="kw">do</span>
<span class="ot">></span> args <span class="ot"><-</span> getArgs
<span class="ot">></span> input <span class="ot"><-</span> <span class="kw">if</span> <span class="fu">null</span> args <span class="kw">then</span> <span class="fu">return</span> example <span class="kw">else</span> <span class="fu">readFile</span> <span class="fu">$</span> <span class="fu">head</span> args
<span class="ot">></span> <span class="fu">putStrLn</span> <span class="fu">$</span> serializeIndentedTree <span class="fu">$</span> forceEither <span class="fu">$</span> parseIndentedTree input
<span class="ot">></span>
<span class="ot">></span> parseIndentedTree input <span class="fu">=</span> runIndent <span class="st">""</span> <span class="fu">$</span> runParserT aTree () <span class="st">""</span> input</code></pre>
<p>The actual parser:</p>
<p>Note that the indents package works by storing a <code>SourcePos</code> in a <code>State</code> monad. Its combinators don't actually consume indentation, they just compare the column numbers. So where we consume <code>spaces</code> is very important.</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">></span> aTree <span class="fu">=</span> <span class="dt">Node</span> <span class="fu"><$></span> many aNode
<span class="ot">></span>
<span class="ot">></span> aNode <span class="fu">=</span> spaces <span class="fu">*></span> withBlock makeNode aNodeHeader aNode
<span class="ot">></span>
<span class="ot">></span> aNodeHeader <span class="fu">=</span> many1 aLeaf <span class="fu"><*</span> spaces
<span class="ot">></span>
<span class="ot">></span> aLeaf <span class="fu">=</span> <span class="dt">Leaf</span> <span class="fu"><$></span> (many1 (satisfy (<span class="fu">not</span> <span class="fu">.</span> <span class="fu">isSpace</span>)) <span class="fu"><*</span> many (oneOf <span class="st">" \t"</span>))
<span class="ot">></span>
<span class="ot">></span> makeNode leaves nodes <span class="fu">=</span> <span class="dt">Node</span> <span class="fu">$</span> leaves <span class="fu"><></span> nodes</code></pre>
<p>An example tree:</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">></span> example <span class="fu">=</span> <span class="fu">unlines</span> [
<span class="ot">></span> <span class="st">"lorem ipsum"</span>,
<span class="ot">></span> <span class="st">" dolor"</span>,
<span class="ot">></span> <span class="st">" sit amet"</span>,
<span class="ot">></span> <span class="st">" consectetur"</span>,
<span class="ot">></span> <span class="st">" adipiscing elit dapibus"</span>,
<span class="ot">></span> <span class="st">" sodales"</span>,
<span class="ot">></span> <span class="st">"urna"</span>,
<span class="ot">></span> <span class="st">" facilisis"</span>
<span class="ot">></span> ]</code></pre>
<p>The result:</p>
<pre><code>% runhaskell parseIndentedTree.lhs
lorem ipsum
dolor
sit amet
consectetur
adipiscing elit dapibus
sodales
urna
facilisis </code></pre>
Announcing feed-push and sendxmpp-pyhttp://changaco.oy.lc/blog/Announcing_feed-push_and_sendxmpp-py/2014-08-29T16:32:52Z2012-04-16T12:30:25Z
<p>Polling RSS/Atom feeds wastes a lot of resources, for example "of all bandwidth generated by [The Pirate Bay] today nearly half comes from the RSS feed"[^1].</p>
<p>Until today I used to poll the feeds of my websites, watching for contributions on wikis and comments on my blog.</p>
<p>Now I receive updates instantly via XMPP thanks to these two scripts:</p>
<p><a href="https://github.com/Changaco/feed-push">feed-push</a> is a daemon that watches local RSS/Atom files for changes and executes commands when new articles appear. It is written in python2 and depends on gamin and feedparser.</p>
<p>sendxmpp is the XMPP equivalent of sendmail, <a href="https://github.com/Changaco/xmpputils">sendxmpp-py</a> is a python3 replacement for the old sendxmpp written in Perl.</p>
<h2 id="rants">Rants</h2>
<p>I couldn't find a cross-platform library to watch files/directories accessible from python to use in feed-push. I fell back to gamin which only works on Linux and FreeBSD at the time I'm writing this post.</p>
<p>sendxmpp should be provided by the XMPP server (in my case prosody) the same way SMTP servers provide sendmail.</p>
<p>There is still no way for a developer to provide a cross-distribution and easy way for users to cleanly install its software, the only tool I know of that tries to solve this problem is <a href="https://gitorious.org/pkgxx">pkg++</a> but it's not even close to being ready.</p>
<p><br></p>
<h2 id="references">References</h2>
<p>[^1]: <a href="https://torrentfreak.com/torrent-less-pirate-bay-sees-massive-drop-in-bandwith-120308/">Torrent-less Pirate Bay Sees Massive Drop in Bandwith</a></p>
DNS problems and alternativeshttp://changaco.oy.lc/blog/DNS_problems_and_alternatives/2014-08-29T16:32:52Z2011-12-10T13:34:21Z
<p>Replacing the <abbr title="Domain Name System">DNS</abbr> is a recurrent topic. In this post I try to explain the problems and give a list of existing or proposed alternatives.</p>
<h2 id="problemsofthedns">Problems of the DNS</h2>
<p>A little terminology first : the DNS has two functions, registering and resolving names. Critics of the registration mechanisms are mostly political, resolution problems are mostly technical.</p>
<h3 id="censorship">Censorship</h3>
<p>The US government has <a href="http://torrentfreak.com/feds-seize-130-domain-names-in-mass-crackdown-111125/">seized many domain names in November 2011</a>, as it had done the year before. Contrary to what some people said, <a href="http://domainincite.com/icann-had-no-role-in-seizing-torrent-domains/">the ICANN was not involved in those operations</a>. It was <a href="http://en.wikipedia.org/wiki/Verisign">Verisign</a>, the operator of the .com, .net, and .name generic top-level domains, that was ordered to seize the domains. As a result, some sites have fled generic TLDs controlled by US companies.</p>
<h3 id="economicvampirismanddomainparking">Economic vampirism and domain parking</h3>
<p>The DNS is a big profitable business.</p>
<p>The name renting (you can't buy a domain name) business works like this : client → registrar (domain manager) → registry (<abbr title="Top-Level Domain">TLD</abbr> manager) → ICANN (root manager). Some of these organizations are nonprofit (e.g. ICANN), but that doesn't mean people working for them don't profit (there are high salaries, expensive dinners, trips, etc). Others are corporations that make very good profits[^1].</p>
<p>X.509 certificates are another business. They are delivered by Certificate Authorities and used in TLS. This security model has been widely criticized[^2][^3][^4] and there are plans to put certificates directly in DNS records[^5][^6], and others to replace X.509 by OpenPGP[^7].</p>
<p>Finally, there is the very annoying <a href="http://en.wikipedia.org/wiki/domain%20parking">domain parking</a> business.</p>
<h3 id="technicalproblems">Technical problems</h3>
<p>Being very old, the DNS also has technical weaknesses.</p>
<p>The first is slow propagation of records because the DNS uses time-based caches.</p>
<p>The second is that records are not stored in a P2P network, but by authoritative servers, which can be taken down by <abbr title="Denial of Service">DoS</abbr> attacks if they aren't sufficiently protected. This is rarely a problem in practice though.</p>
<h2 id="whyhaventtheproblemsbeensolvedyet">Why haven't the problems been solved yet ?</h2>
<p>Well, because different people want things that are contradictory. The problem is often known as <a href="http://en.wikipedia.org/wiki/Zooko%27s%20triangle">Zooko's triangle</a>, but there are in fact more than three desirable properties for identifiers :[^8]</p>
<ul>
<li>We want to <strong>choose</strong> a <strong>unique</strong> and <strong>memorable</strong> name so we can communicate it to somebody else even if we don't have our computer with us at the moment. Some people who always have their smartphone with them may argue that this property is not important anymore, but not everybody has a smartphone.</li>
<li>We want a <strong>censorship-free</strong> system.</li>
<li>We want our <strong>trademarks</strong> to be registered only by us.</li>
<li>We want links between documents that are <strong>stable in time</strong>, the Web doesn't like broken URLs.</li>
<li>We want the registration process to be <strong>easy, fast and free of charge</strong>.</li>
<li>We want a name to be <strong>resolvable</strong> to an address, otherwise it's of no use to us.</li>
<li>We want names that are <strong>recoverable</strong> in case of hijacking or loss of credentials.</li>
</ul>
<h2 id="existingorproposedalternatives">Existing or proposed alternatives</h2>
<p>I can't help but start by my own DNS replacement proposal. <img src="http://changaco.oy.lc/smileys/smile.png" alt=":)" /> The <a href="http://changaco.oy.lc/ins/">Internet Naming System</a> acknowledges that there is no perfect solution and chooses to keep a central authority for name allocation. It makes censorship automatically detectable but not impossible.</p>
<p>Projects for P2P registration of names :</p>
<ul>
<li><a href="http://dot-bit.org/">Dot-BIT</a> (<a href="irc://irc.freenode.net/namecoin">#namecoin on freenode</a>) uses Bitcoin-like proof-of-work (which assumes that honest nodes have the majority of computing power)</li>
<li><a href="http://www.p2pns.org/">P2PNS</a> assumes that a vast majority of peers is honest</li>
<li><a href="http://lauren.vortex.com/archive/000787.html">IDONS: Internet Distributed Open Name System</a> (<a href="http://forums.gctip.org/forum-34.html">forum</a>) seems dead</li>
<li><a href="irc://irc.efnet.org/dns-p2p">#dns-p2p</a>, which used to have a wiki on dot-p2p.org, never gave anything and is dead</li>
</ul>
<p>Technical solutions for improving resolution :</p>
<ul>
<li><a href="http://beehive.systems.cs.cornell.edu/codons.php">CoDoNS</a></li>
<li><a href="http://huitema.wordpress.com/2011/01/03/a-simple-p2p-dns-proposal/">A simple P2P DNS proposal</a></li>
</ul>
<p>Other projects :</p>
<ul>
<li><a href="http://opennicproject.org/">OpenNIC</a> (<a href="irc://irc.freenode.net/opennic">#opennic on freenode</a>, <a href="http://lists.darkdna.net/mailman/listinfo">OpenNIC lists</a>) is an alternative root</li>
<li><a href="http://dns.telecomix.org/">Telecomix Censorship-proof DNS</a> (<a href="irc://irc.telecomix.org/dns">#dns on telecomix IRC</a>)</li>
</ul>
<p>Other proposals :</p>
<ul>
<li>on the <a href="http://lists.zooko.com/mailman/listinfo/p2p-hackers">p2p-hackers list</a> :
<ul>
<li><a href="http://lists.zooko.com/pipermail/p2p-hackers/2010-December/002598.html">Secure, decentralized DNS (a.k.a. solving Zooko's triangle)</a></li>
<li><a href="http://lists.zooko.com/pipermail/p2p-hackers/2010-December/002587.html">.p2p domain</a></li>
</ul></li>
<li><a href="http://roland.entierement.nu/blog/2010/10/02/for-a-truly-acentric-internet.html">For a truly acentric Internet</a>, proposes to abandon meaningful identifiers (an old proposition that comes back regularly)</li>
<li><a href="http://www.templetons.com/brad/dns/">Problems, Goals and a Fix for Domain Names</a>, proposed to only allow trademarks as TLDs</li>
</ul>
<h2 id="referencesandcredits">References and credits</h2>
<p>[^1]: <a href="http://www.chemla.org/textes/voleur.html">Confessions d'un voleur</a> [fr]</p>
<p>[^2]: <a href="https://www.eff.org/deeplinks/2010/03/researchers-reveal-likelihood-governments-fake-ssl">New Research Suggests That Governments May Fake SSL Certificates</a></p>
<p>[^3]: <a href="https://docs.google.com/present/view?id=df9sn445_206ff3kn9gs">It's Time to Fix HTTPS</a></p>
<p>[^4]: <a href="http://lair.fifthhorseman.net/~dkg/tls-centralization/">Technical Architecture shapes Social Structure: an example from the real world</a></p>
<p>[^5]: <a href="http://tools.ietf.org/wg/dane/">DNS-based Authentication of Named Entities - IETF Working Group</a></p>
<p>[^6]: <a href="http://www.bortzmeyer.org/jres-dane-2011.html">Exposé sur les clés dans le DNS à JRES</a> [fr]</p>
<p>[^7]: <a href="http://web.monkeysphere.info/">The Monkeysphere Project</a></p>
<p>[^8]: <a href="http://www.bortzmeyer.org/no-free-lunch.html">Inventer un meilleur système de nommage: pas si facile</a> [fr]</p>
<p>Thanks to Stéphane Bortzmeyer for helping with this post.</p>
Privacy and distant storagehttp://changaco.oy.lc/blog/Privacy_and_distant_storage/2014-08-29T16:32:52Z2010-08-30T22:45:55Z
<p>Some people seem to think that their data is only safe in their own homes. I agree that not keeping a local copy or storing unprotected personal documents on a machine you don't control are bad things. But I was reminded today (while trolling on <a href="http://www.numerama.com/">Numerama</a>, a French tech-related news site) that having them home doesn't make them safe from:</p>
<ul>
<li>hardware failures such as hard drive breakdowns (although <a href="http://smartmontools.sourceforge.net/">smartmontools</a> may be able to alert you before it is too late)</li>
<li>disasters such as fire</li>
</ul>
<p>Of course, if your home burns, loosing your files will be the least of your concerns, but if you know they are safe it is one less thing to worry about.</p>
<p>Then I realized that having backups in different geographic places does not necessarily endanger your privacy, it just depends on how you do it. What you need is to encrypt and/or cut the data so that the people who will store it for you will not be able to read or exploit it (just like <a href="http://en.wikipedia.org/wiki/Freenet">Freenet</a> does for different reasons).</p>
<p>So the next question is where to store it ? I came to see three possibilities:</p>
<ul>
<li>pay for some storage service, might be necessary if you have a lot of data</li>
<li>share storage space with peers, this was my original thought</li>
<li>share storage space with family and/or friends, this the safest of the three and credit goes to Kaliko for suggesting it to me in a chat room</li>
</ul>
<p>I believe, like many others, that a good place for such sharing software is in <a href="http://en.wikipedia.org/wiki/residential%20gateway">residential gateway</a>s, maybe we'll see it implemented someday in the <a href="http://wiki.debian.org/FreedomBox">Freedom Box</a> ?</p>
Code indentation and alignmenthttp://changaco.oy.lc/blog/Code_indentation_and_alignment/2012-04-16T12:31:10Z2010-06-01T15:09:22Z
<p>In this post I try to summarize the different points of view on the tabs versus spaces war.</p>
<h2 id="decompositionoftheproblem">Decomposition of the problem</h2>
<p>Firstly, you need to understand the difference between the <strong>tab key</strong> and the <strong>tab character</strong>. What your text editor does when you press the tab key is a matter of configuration and has nothing to do with the problem discussed here.</p>
<p>Secondly, we need to distinguish <strong>indentation</strong> and <strong>alignment</strong>, this is explained in <a href="http://www.iovene.com/61">TABs vs Spaces. The end of the debate.</a> and shows why the historical rendering of tabs is not fit for alignment.</p>
<h2 id="thesolutions">The solutions</h2>
<h3 id="useonlyspaces">Use only spaces</h3>
<p>This is the solution proposed by many and is notably exposed in <a href="http://www.jwz.org/doc/tabs-vs-spaces.html">Tabs versus Spaces: An Eternal Holy War.</a></p>
<p>The obvious solution when dynamic doesn't work is to fall back to static. Using only spaces does indeed work for both indentation and aligning and you can configure most text editors to make it as easy as using tabs. So, what's wrong with it ? Here's a list :</p>
<ul>
<li>you can't use proportional fonts</li>
<li>you can't easily change the indentation width</li>
<li>your files are larger</li>
</ul>
<p>The two first points are all about freedom, maybe you don't like proportional fonts to code, but some people do.</p>
<p>As to the third point, people usually reject it by saying that it doesn't matter nowadays because of disks capacity, network speed and compression. Still, I wanted to make a <em>quick and dirty</em> measure of the impact of the 4 spaces policy on python 2.6 on my system as of June 2010 ( done in zsh ) :</p>
<pre><code># cd /usr/lib/python2.6
# for f in **/*(/); do mkdir -p "../python2.6.spaces/$f" "../python2.6.tabs/$f"; done;
# for f in **/*.py; do cp "$f" "../python2.6.spaces/$f"; cp "$f" "../python2.6.tabs/$f"; done;
# du -h --max-depth=0 python2.6.*
43M python2.6.spaces
43M python2.6.tabs
# cd ../python2.6.tabs
# sed 's/^\(\t*\) /\1\t/' -i **/*.py
# du -h --max-depth=0 ../python2.6.tabs
41M ../python2.6.tabs
# sed 's/^\(\t*\) /\1\t/' -i **/*.py
# du -h --max-depth=0 ../python2.6.tabs
39M ../python2.6.tabs
... I did it two more times but the rounded number stayed 39M
</code></pre>
<p>The result is that using 4 spaces instead of tabs makes files about 10% bigger. If you get a different result or tested something else than python 2.6 I invite you to post a comment.</p>
<h3 id="usespacesforalignment">Use spaces for alignment</h3>
<p>Since the problem with tabs is alignment, some people argue that you can use whatever you want for indentation as long as you use spaces for alignment. If you choose to use tabs, the indentation width is no longer an issue and most of the space waste goes away, but you still can't use proportional fonts.</p>
<h3 id="elastictabstops">Elastic tabstops</h3>
<p>This solution solves all the issues listed here and makes alignment easier. How ? By redefining the way the tab character is displayed. It's all explained in <a href="http://nickgravgaard.com/elastictabstops/">Elastic tabstops - a better way to indent and align code</a>. The downside is that text editors have to be modified.</p>
<h2 id="myopinion">My opinion</h2>
<p>I use tabs for indentation, spaces for alignment and I wish elastic tabstops were more widely known, implemented and used.</p>