<?xml version="1.0"?>
<rss xmlns:a="http://www.w3.org/2005/Atom" xmlns:dt="http://xsltsl.org/date-time" version="2.0">
  <channel>
    <title>Yoan Blanc’s weblog</title>
    <link>http://yoan.dosimple.ch/blog/</link>
    <description>The boring weblog of Yoan
	Blanc</description>
    <item>
      <title>Writing testable JavaScript</title>
      <link>http://yoan.dosimple.ch/blog/2010/02/06</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2010/02/06</guid>
      <pubDate>Sat, 06 Feb 2010 17:02:00 +0100</pubDate>
      <category>JavaScript jQuery YUI</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
When some people still focus on documentation, I tend to slip on saying that it’s not that important.
</p><blockquote xmlns="http://www.w3.org/1999/xhtml">
<p><em>“Working software over comprehensive documentation”</em></p>
<p><a xmlns="" href="http://agilemanifesto.org/">Manifesto for Agile Software Development</a></p>
</blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Most of us already know about unobtrusive JavaScript and how good it is. Maybe also about event delegation and how many listeners you are sparing with that little technique (thanks to <a xmlns="" href="http://api.jquery.com/closest/">jQuery’s closest</a>). I’ll be a bit more generalist here and talking about writing code that enable you to test them with unit tests (using QUnit, YUI, …).
</p><p xmlns="http://www.w3.org/1999/xhtml">
Before you think about it, yes <strong>Test Driven Development</strong> or <strong>Behavioural Driven Development</strong> (which are very close if you do the first one right) will force to you do so. If you know those, go with them but the following pitfalls might still be interesting.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Don’t use the module pattern when you really mean class.
</p><pre xmlns="http://www.w3.org/1999/xhtml">var Foo = {
 init: function(state) {
  this.state = state;
 }
}

Foo.init(42);</pre><p xmlns="http://www.w3.org/1999/xhtml">
How many instances of <code>Foo</code> can you have on your page once initialized ? The answer is one as this represent a kind of singleton. It also means that you won’t be able to test as many instances as you want representing tons of different cases. Stick with the good ol’ way.
</p><pre xmlns="http://www.w3.org/1999/xhtml">function Foo(state) {
 this.state = state;
}

new Foo(42);</pre><p xmlns="http://www.w3.org/1999/xhtml">
Stay away from id’s as well for the same reason and try to use classes instead. It means no <code>document.getElementById</code> within <code>Foo</code>’s constructor.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Separate the content from the logic, you JavaScript module/class should be about the logic only. Strings, translations, configuration, ... should be kept outside. Giving a JSON structure as only parameter of a constructor is common and readable.
</p><pre xmlns="http://www.w3.org/1999/xhtml">new Foo({
 class: "foo",
 quantity: 42
});</pre><p xmlns="http://www.w3.org/1999/xhtml">
<a xmlns="" href="http://api.jquery.com/jQuery.extend/">jQuery’s extend</a> (YUI’s ..., Prototype ...) offer a good way to mix good default values with configuration.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Next one is loose coupling. Being sure that a module what work as well alone or when it has to interact with many other ones is key when building big and complexe systems.
</p><p xmlns="http://www.w3.org/1999/xhtml">
The involved technique is to rely on an event mechanism. On a very safe web environment (like Opera widgets, Pre application, Apple dashboard, …), DOM3 events can be used. You only have be tied to a DOM node to fire them. YUI implements an easy to use Observer pattern (called <a xmlns="" href="http://developer.yahoo.com/yui/event/#customevent">CustomEvent in YUI2</a>), jQuery offers something similar which integrates with how it manages DOM events (Prototype as well).
</p><pre xmlns="http://www.w3.org/1999/xhtml"><i>// b will send data to a</i>
var a = new A();
var b = new B(a);

<i>// or</i>
var a = new A();
var b = new B();
a.onChange(b.onChanged, b);</pre><p xmlns="http://www.w3.org/1999/xhtml">
Those are very similar, thus it seems easier to adapt, test or reuse. Isn’t it?terminal
</p><p xmlns="http://www.w3.org/1999/xhtml">
And last but not least, don’t put your init in the libraries/modules/… Anything that involves <code>onload</code>, <code>DOMContentReady</code>, … is tied to a particular usage already and shouldn’t live into a library or module imho.
</p><pre xmlns="http://www.w3.org/1999/xhtml">function A(element) {
 <i>// whatever</i>
}

$(document).ready(function() {
	new A($("#a")[0]);
});</pre><p xmlns="http://www.w3.org/1999/xhtml">
It means that those two blocks of code should live separately. At last in your developement environment. Then, you’re totally free to join, compress and maybe obfuscate them as you won’t test or develop against that version.
</p><p xmlns="http://www.w3.org/1999/xhtml">
And it’s more a personal taste issue here. I don’t like stuff that are automagically loaded because of a particular class name or id.
</p><p xmlns="http://www.w3.org/1999/xhtml">
If you see more of them, feel free to contribute.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Si le must reste de pratiquer le développement piloté par les tests (TDD) ou <em>« comportemental »</em> (<em xml:lang="en">Behavioural</em>), il me semble judicieux de pointer différents points qui vont être des freins à la mise en place de tests. En somme des mauvaises pratiques où la justification est qu’elles rendent problématique la mise en place d’une assurance qualité.
</p><ul xmlns="http://www.w3.org/1999/xhtml">
<li>Mon préféré est le <em xml:lang="en">module pattern</em>, qui cache un singleton, donc état global ce qui implique des difficultés à une éventuelle réutilisation.</li>
<li>Mélanger l’instanciation et la définition. Il est plus aisé d’effectuer des tests sur une portion ne faisant rien par défaut, ne s’initialisant magiquement dès qu’elle le peu. Séparer la définition de l’usage est important.</li>
<li>Fournir de bons défauts mais offrir des possibilités de modification. Un but premier est la réutilisabilité et, chose souvent ignorée, l’interopérabilité entre différents modules, bibliothèques. Et dans une certaine mesure le fait qu’il faille peut-être offrir une version dans la langue de l’utilisateur.</li>
<li>Pas d’<code>id</code> en dur, uniquement des classes. Pour la simple et bonne raison qu’une id est unique et sera toujours indépendante de votre module/bibliothèque.</li>
<li>Couplage faible entre modules, voire aucun couplage. Si deux éléments doivent communiquer pensez à leur offrir un canal approprié et ne leur donnez pas la possibilité de le faire directement. Il existe pléthore de solutions via DOM3 ou la bibliothèque de votre choix.</li>
<li>Et peut-être le plus évident, écrivez des tests. Car la réalité vaudra tous les discours du monde.</li>
</ul><p xmlns="http://www.w3.org/1999/xhtml">
Il n’est jamais simple de franchir le pas, de s’y mettre, d’oser les tests. C’est un investissement valable. N’hésitez pas à agrémenter la liste ci-dessus de vos expériences personnelles.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>PHP is a templating language</title>
      <link>http://yoan.dosimple.ch/blog/2010/01/12</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2010/01/12</guid>
      <pubDate>Tue, 12 Jan 2010 22:02:00 +0100</pubDate>
      <category>APC PHP doSimple</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
For my last project, I had to use <abbr title="PHP Hypertext Preprocessor">PHP</abbr> and managed to make it fun by —among other stuff— rewriting a templating tool. Templates was one of the first thing we did with <a xmlns="" href="http://batiste.dosimple.ch/">Batiste</a> for <a xmlns="" href="http://dosimple.ch">doSimple</a>. It was <a xmlns="" href="http://dosimple.ch/articles/Template/" hreflang="fr">qregexp based</a>, not very flexible, ugly and for sure, inefficient.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Let’s redo this, keeping in mind that <a xmlns="" href="http://www.php.net">PHP</a> is already a templating language.
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;!DOCTYPE html&gt;
&lt;html lang=<b>&lt;?php</b> echo $lang <b>?&gt;</b>&gt;
<b>&lt;?php</b> echo $html <b>?&gt;</b>
&lt;/html&gt;
</pre><p xmlns="http://www.w3.org/1999/xhtml">
This is valid PHP, and can be seen as a template with two parameters: the language (<code>$lang</code>) and some html content (<code>$html</code>).
</p><pre xmlns="http://www.w3.org/1999/xhtml"><b>&lt;?php</b>
$lang = "en";
$html = "&lt;h1&gt;Hello World!&lt;/h1&gt;";
<i>// the file above</i>
include("hello.php");
</pre><p xmlns="http://www.w3.org/1999/xhtml">
That was too easy. But it’s not very clean, imho because you cannot do anything with the result. Let’s do this a little bit better.
</p><pre xmlns="http://www.w3.org/1999/xhtml"><b>&lt;?php</b>
function template($template, $args) {
 extract($args);
 ob_start();
 include($template);
 $result = ob_get_contents();
 ob_end_clean();
 return $result;
}

echo template("hello.php",
              array("lang" =&gt; "en",
                    "html" =&gt; "&lt;h1&gt;Hello, World!&lt;/h1&gt;"));
</pre><p xmlns="http://www.w3.org/1999/xhtml">
This way, you don’t pollute the global scope with variables and are able to reuse templates. It’s still very, very basic but will enable you to understand the final class Template that is used by <a xmlns="" href="http://www.bluespirit.ch">bluespirit.ch</a>. I’ll show you how it works but let you dive into the PHP code to understand it.
</p><pre xmlns="http://www.w3.org/1999/xhtml"><b>&lt;?php</b>
<i>// templates is a directory</i>
$tpl = new Template("templates");

echo $tpl-&gt;index(array("title" =&gt; "Hello",
                       "links" =&gt; array(1,2,3));
</pre><p xmlns="http://www.w3.org/1999/xhtml">
Now the templates, let’s start with the index (the function call above is in fact using <a xmlns="" href="http://php.net/__call">__call</a>).
</p><pre xmlns="http://www.w3.org/1999/xhtml"><b>&lt;?php</b>
$this-&gt;inherits("layout");
$this-&gt;block("head")
<b>?&gt;</b>
&lt;title&gt;<b>&lt;?php</b> echo $title <b>?&gt;</b>&lt;/title&gt;
<b>&lt;?php</b>
$this-&gt;endblock();
$this-&gt;block("body")
<b>?&gt;</b>
&lt;h1&gt;<b>&lt;?php</b> echo $title <b>?&gt;</b>&lt;/h1&gt;
&lt;ul&gt;
<b>&lt;?php</b>
foreach($links as $link):
<b>?&gt;</b>
&lt;li&gt;<b>&lt;?php</b> echo $this-&gt;link(array("link" =&gt; $link)) <b>?&gt;</b>&lt;/li&gt;
<b>&lt;?php</b>
endforeach
<b>?&gt;</b>
&lt;/ul&gt;
<b>&lt;?php</b>
$this-&gt;endblock();
</pre><p xmlns="http://www.w3.org/1999/xhtml">
The layout, from which this template inherits.
</p><pre xmlns="http://www.w3.org/1999/xhtml">
&lt;!DOCTYPE html&gt;
&lt;html lang=en&gt;
&lt;head&gt;
&lt;meta charset=utf-8&gt;
<b>&lt;?php</b> $this-&gt;block("head") <b>?&gt;</b>
&lt;title&gt;Untitled Document&lt;/title&gt;
<b>&lt;?php</b> $this-&gt;endblock() <b>?&gt;</b>
&lt;/head&gt;
&lt;body&gt;
<b>&lt;?php</b>
$this-&gt;block("body");
$this-&gt;endblock()
<b>?&gt;</b>
&lt;/body&gt;
&lt;/html&gt;
</pre><p xmlns="http://www.w3.org/1999/xhtml">
and link, of course.
</p><pre xmlns="http://www.w3.org/1999/xhtml"><b>&lt;?php</b>
echo $link
</pre><p xmlns="http://www.w3.org/1999/xhtml">
Which could have been more complex.
</p><p xmlns="http://www.w3.org/1999/xhtml">
That’s the very basics, the final one includes more features like some block control meaning you can no only override a block but also append or prepend some content which is very useful for the usual end of the page scripts. Another one that I like very much is some cache (using <a xmlns="" href="http://php.net/apc">APC</a> (or <a xmlns="" href="http://github.com/greut/apc_alt">apc_alt</a>) enabling avoiding regenerating a piece of layout everytime.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Having this kind of cache also means that you might ending up doing bad things in the templates (views) like SQL requests. This is for example used on the homepage of <a xmlns="" href="http://www.bluespirit.ch/">bluespirit.ch</a> where the news are coming from a RSS feed parsed by <a xmlns="" href="http://pipes.yahoo.com">Yahoo! Pipes</a>. It doesn’t <a xmlns="" href="http://www.wait-till-i.com/2009/12/18/curl-your-view-source-of-the-web/" title="cURL &#x2013; your &#x201C;view source&#x201D; of the web">cURL it</a> all the time.
</p><p xmlns="http://www.w3.org/1999/xhtml">
All this in <a xmlns="" href="http://github.com/greut/template">on GitHub</a>, get it, fork it, fix it. And I’ve got one question for the PHP masters in the room, how do you do monkeypatching in PHP? (I know how much evil it is, but I promise that I won’t break anything)
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Un des premiers outils que nous avions réalisés avec <a xmlns="" href="http://batiste.dosimple.ch">Batiste</a> dans le cadre de nos débuts dosimplesques (pardonnez ce néologisme) a été un système de template. Nous en avons fait <a xmlns="" href="http://dosimple.ch/articles/Template/" hreflang="fr">quelques-uns</a> <a xmlns="" href="http://dosimple.ch/articles/TempLight/" hreflang="fr">même</a>. Tous reposent sur une syntaxe proche d’HTML, donc à base de commentaires remplacés à l’exécution.
</p><p xmlns="http://www.w3.org/1999/xhtml">
C’était sans bien réaliser que PHP est déjà un langage de templating, intrinséquement. Pourquoi serait-il indispensable de mettre ce <code>&lt;?php</code> sinon ? Ceci étant dit, voici un système de templates reposant sur ce fait-là et offrant quelques fonctionnalités sympathiques, telles que : l’héritage, les blocs, l’inclusion d’autres templates, le cache et même l’envoi de headers HTTP pour les plus bidouilleurs d’entre vous.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Le code ainsi que des exemples se trouvent sur <a xmlns="" href="http://github.com/greut/template">GitHub</a>, amusez-vous y.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>MMIX</title>
      <link>http://yoan.dosimple.ch/blog/2009/12/31</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2009/12/31</guid>
      <pubDate>Thu, 31 Dec 2009 20:47:00 +0100</pubDate>
      <category>2009 Opera Eboutic Life</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
It’s been more than 10 years now that I made my first website (using Netscape Composer). Apart the fact that I loved it, nobody would have been able to say that I still would be doing that today. Here comes the quick last year review and the try of getting an overview of next year. Promising as far as I can tell. I’m realizing that I didn’t do any last year, what a mistake.
</p><p xmlns="http://www.w3.org/1999/xhtml">
So in 2009, I left Oslo and the web application team of Opera Software because I wasn’t happy. Not being able to fully enjoy the Friday beer might be a cause or not.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Back in Switzerland I was able to take some time with my former girlfriend, visiting her and some friends of her in Germany. I still wanted to work on some projects but I realize now that it was stupid to not being able to do one thing at the time and appreciate it.
</p><p xmlns="http://www.w3.org/1999/xhtml">
In June, I joined <a xmlns="" href="http://www.eboutic.ch/">eboutic.ch</a> as a Rails developer. Those guys weren’t afraid to pick someone who never done anything serious with Ruby on Rails before. Hopefully <a xmlns="" href="http://www.accolade.ch/" hreflang="fr">Raphaël</a> was there to guide me and show me the way when I was being to pythonic or, even worse, phpish. In the six month I spent there, we actually manage to do some big stuff and that is really a good achievement for the company itself. Migrating to a very fresh version of Rails, revamping all the HTML during the redesign, auto-magically generating the daily mailing (that were done by hand before that, every single day) and many more.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Excuse me if I offend you, but the more I work with different technologies the more I realize that the differences between them is basically the syntax of the language itself. As Paul Graham would have said, Ruby is an acceptable Lisp. I’m back at hacking in PHP since a couple of weeks, and it’s, sometimes, quite painful.
</p><p xmlns="http://www.w3.org/1999/xhtml">
During that time, I lived in a couple of flats, looking for a room or waiting for September to know what would have happened on her side. All the flat I lived in or visited sucked. My job was getting on my nerves and I had the feeling to be stuck in a dead-end. So, I blew everything up. Locality, job, girlfriend, ... It’s time to take the time of doing things like I feel them, or to feel them.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Thanks to Paris Web, and the people I met there who told me what I already knew but could see myself. I’ve been travelling between city, jumping from jobs to jobs for more than 3 years now. This is what I like doing: being a pain in the arse, getting stuff done on time, putting some quality, learning stuffs and travelling (it doesn’t have to be far).
</p><p xmlns="http://www.w3.org/1999/xhtml">
So since this month, I’m a (no-yet-too-expensive-)freelancer, I’ve got a flat in Neuchâtel (which is a complete heresy for almost all my friends, the one who didn’t already reject me). I’m looking forward to enjoying this city even more.
</p><p xmlns="http://www.w3.org/1999/xhtml">
As a side thing, thanks to the professor who supervized my diploma (in 2006) I had the opportunity to give a 2 hours JavaScript crash course including an introduction about the awesomeness of getting a new job every six months. And to act as an expert for diploma. It’s good but very hard to go back into the school reality. I knew the gap was huge but felt in it nonetheless.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Enough with last year, let’s look at the bright future. More weddings and children to come. Not mine, but it makes me feeling how good it was to be innocent. Innocent doesn’t mean nice at least not applied to myself.
</p><p xmlns="http://www.w3.org/1999/xhtml">
On the work side, the challenge will be to find a (correct) balance between working and doing anything else that doesn’t involve any kind of computer. Pure utopy, but it’s good to start trying at some point. Another one will be having enough work.
</p><p xmlns="http://www.w3.org/1999/xhtml">
And last but not least, my mother is leaving Switzerland for starting over in Corsica. I’ll have to take care of some of her furnitures but most important the cats for a couple of month. Two devils worse that kinds because it’s totally hopeless to believe in educating a cat.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Feel free to drop me an e-mail if you have some mice for the cats, some freetime or a need for a couch. I’ll be pleased to help.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Et voilà une année qui se clôt, et un énième blog post pour raconter sa vie et se congratuler. Puisque ça fait un peu plus de 10 ans que je joue avec le web, et que je n’ai pris le temps de faire ce type d’écrit là l’an dernier. Le voici avec un petit aperçu de l’année à venir.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Il y a un an, je me gavais la panse dans un hôtel pour backpacker à Interlaken, puis la suite est moins joyeuse. Sinon, j’étais alors employé par Opera Software, basé à Oslo, depuis deux mois et pour deux mois encore (environ). Bref, <a xmlns="" href="http://www.aaronsw.com/weblog/management" hreflang="en">ceci</a> a conduit à ce que j’en sorte d’une certaine manière.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Pour retourner au pays des modzons, tenter des idées personnelles, retrouver un peu celle que j’y avais laissé. Même si elle s’en était déjà retourné dans son Allemagne natale, à 9h de train de là. Quelques semaines, donc une au Nord de Hambourg m’ont permis de changer d’air. Même si j’aurais pu/dû débrancher un peu plus. C’est dur de lâcher du lest quand le futur est indécis.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Et j’ai rejoins <a xmlns="" href="http://www.eboutic.ch/">eboutic.ch</a> pour y faire du Rails en n’en ayant jamais fait. Un retour sous Mac OS de bonne augure. Au niveau développement j’y ai eu beaucoup de plaisir. Un mélange de challenge, de nouveauté et de responsabilité. Quelques jolis chantiers y ont été abattu.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Puis une envie de tout envoyer balader, une nécessité. Ville, copine, job pour être un peu plus honnête envers moi-même et les autres ce qui je suis et ce que j’aime faire. Je suis vraiment quelqu’un à double tranchant demandant autant qu’il donne. Et je chéris ses petits moments ou ça chauffe un peu, malgré tout.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Les rencontres faites à Paris Web m’ont décidément conforté dans l’envie de me lancer en solitaire. D’offrir mes services çà et là. Au fond, c’est tout de même plus honnête que de changer de job tous les 6 mois. L’excitation de la nouveauté plus être dans un élément fixé dans le temps font que je m’y plais déjà. Premier mandat devant voir le jour ce soir à minuit.
</p><p xmlns="http://www.w3.org/1999/xhtml">
En parallèle, j’ai donné un petit cours à la HE-ARC de St-Imier plus suis un diplômant en tant qu’expert (une vraie plaie d’expert que je fais). Le fossé entre l’école et l’industrie derrière est grand. Du moins dans le domaine qui m’affectionne. Difficile d’avoir une approche adaptée si tant est que j’en soie capable.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Et voilà, 2010 démarre. J’ai élu domicile en ville de Neuchâtel (à deux pas de la gare). Pour ceux qui ne connaissent pas l’éternelle gué-guerre que jouent le Haut et le Bas du canton de Neuchâtel, c’est un affront énorme que j’ai commis.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Quelques projets sur le feu, des billets pour Lift10, pour (potentiellement) une semaine à ski avec des enfants de 5ème primaire et la niak des débuts. Je pars confiant et ça fait du bien. Il me faut réellement trouver une hygiène entre boulot et le reste (ne nécessitant aucun outil informatisé). Même si c’est en prenant le large de temps à autre, histoire de faire un coupure.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Donc voilà, si vous passez par là ou pensez passer par là, y’a de la place, n’hésitez pas.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Python web app as an egg with Paste, Fabric and Spawning</title>
      <link>http://yoan.dosimple.ch/blog/2009/11/28</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2009/11/28</guid>
      <pubDate>Sat, 28 Nov 2009 13:23:00 +0100</pubDate>
      <category>Fabric Paster Python Spawning WSGI</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
One of the major success of PHP is how easily you can deploy PHP applications. Thanks mod_php for that. Python or Ruby requires quite more work even though it’s not that painful if your using something like <a xmlns="" href="http://www.modrails.com/" hreflang="en">Passenger with Ruby</a>. I’m still looking for a way that I find brilliant. So I played with <a xmlns="" href="http://pythonpaste.org/" hreflang="en">Paste</a>, <a xmlns="" href="http://pypi.python.org/pypi/Spawning" hreflang="en">Spawning</a> and <a xmlns="" href="http://peak.telecommunity.com/DevCenter/setuptools" hreflang="en">setuptools</a> to build a very minimalist <a xmlns="" href="http://yoan.dosimple.ch/blog/2009/01/31/" hreflang="en" title="Playing with Middlewares">WSGI application</a> you deploy without any pain using <a xmlns="" href="http://fabfile.org" hreflang="en">Fabric</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Before we start, you can find the code bellow on <a xmlns="" href="http://gist.github.com/235338" hreflang="en">GitHub</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
First the <code>setup.py</code> file that describe our application:
</p><pre xmlns="http://www.w3.org/1999/xhtml">from setuptools import setup, find_packages

setup(name="app",
      version="0.1",
      description="example application",
      long_description="",
      keywords="",
      author="Yoan Blanc",
      author_email="yoan.at.dosimple.ch",
      url="http://yoan.dosimple.ch/blog/",
      license=’All rights reserved’,
      packages=find_packages(),
      zip_safe=False,
      install_requires=[],
      entry_points={"paste.app_factory": ["main=app:make_app"]},
     )</pre><p xmlns="http://www.w3.org/1999/xhtml">
It’s all standard except the entry point called <code>paste.app_factory</code> that will be used by Paste to create the WSGI application. For the Djangoist here, Paster acts like your <code>manage.py</code>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Make the <a xmlns="" href="http://wsgi.org" hreflang="en">WSGI</a> application itself, into <code>app/__init__.py</code>:
</p><pre xmlns="http://www.w3.org/1999/xhtml">def application(environ, start_response):
 start_response("200 OK",
                [("Content-Type", "text/html")])
 return ["&lt;h1&gt;Hello World!&lt;/h1&gt;"]</pre><p xmlns="http://www.w3.org/1999/xhtml">
And the factory (called <code>make_app</code> inside <code>setup.py</code>) is required as well in the same file.
</p><pre xmlns="http://www.w3.org/1999/xhtml">def make_app(global_conf, **app_conf):
    return application</pre><p xmlns="http://www.w3.org/1999/xhtml">
Now, you might be wondering how this make_app is called. Paste works with <em>ini</em> files that decribe your configuration, from the app your using to the database, the server, logs, and so on. It’s very handy to replicate the same kind of environment you find when working with Ruby on Rails by having different ini files for each.
</p><p xmlns="http://www.w3.org/1999/xhtml">
So there is the <code>app.ini</code>:
</p><pre xmlns="http://www.w3.org/1999/xhtml">[app:main]
use = egg:app

[server:main]
use = egg:Spawning
host = 127.0.0.1
port = 8000
num_processes = 1
threadpool_workers = 1</pre><p xmlns="http://www.w3.org/1999/xhtml">
The first section describes the application to use. It’s the egg that setuptools will create and install. That’s right, your application is exactily like any other python package. It means dependencies resolution, updates,… And the second part describe which server paster will have to use to run it. Spawning is a very efficient server that handles graceful code reloading. Pure happiness.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Before you can run it using :
</p><pre xmlns="http://www.w3.org/1999/xhtml">$ paster serve app.ini</pre><p xmlns="http://www.w3.org/1999/xhtml">
You’ll have to install it.
</p><pre xmlns="http://www.w3.org/1999/xhtml"># python setup.py develop</pre><p xmlns="http://www.w3.org/1999/xhtml">
<code>develop</code> means it symlinks the package to your directory and you won’t have to reinstall it later to take into account the changes made.
</p><p xmlns="http://www.w3.org/1999/xhtml">
It should run just perfectly. Now let’s worry about deploying it somewhere else. Local web applications are nice but sharing them is cool too.
</p><p xmlns="http://www.w3.org/1999/xhtml">
This is the <code>fabfile.py</code>, Fabric is more or less like <a xmlns="" href="http://www.capify.org/" hreflang="en">Capistrano</a> (Ruby):
</p><pre xmlns="http://www.w3.org/1999/xhtml">from __future__ import with_statement
from fabric.api import env, run, put, local, cd

env.hosts = ["localhost"]
env.path = "~/www/app"

def build_egg():
    local("python setup.py bdist_egg")

def cleanup():
    local("rm -rf build")
    local("rm -rf dist")

def start():
    with cd(env.path):
        run("PYTHONPATH=app.egg paster serve app.ini"
            "--daemon --pid-file=app.pid")

def stop():
    with cd(env.path):
        run("paster serve --stop-daemon "
            "--pid-file=app.pid")

def deploy():
    build_egg()
    put("app.ini", env.path)
    put("dist/*.egg", env.path+"/app.egg")
    cleanup()</pre><p xmlns="http://www.w3.org/1999/xhtml">
A pythonic Makefile, more or less that has special power to deal with deployment. This how you can use it.
</p><pre xmlns="http://www.w3.org/1999/xhtml">$ fab deploy
$ fab start</pre><p xmlns="http://www.w3.org/1999/xhtml">
It created a .egg, uploaded it to the destination and started the Spawning server using Paster. It will run on the port <code>8080</code>, to see it on the port 80 I’d use something like <a xmlns="" href="http://nginx.net/" hreflang="en">Nginx</a> as a proxy. But it’s a different story (and very simple by the way).
</p><p xmlns="http://www.w3.org/1999/xhtml">
After you made some changes simple run:
</p><pre xmlns="http://www.w3.org/1999/xhtml">$ fab deploy</pre><p xmlns="http://www.w3.org/1999/xhtml">
to see them live.
</p><pre xmlns="http://www.w3.org/1999/xhtml">$ fab stop</pre><p xmlns="http://www.w3.org/1999/xhtml">
Will stop the server.
</p><p xmlns="http://www.w3.org/1999/xhtml">
How awesome is that?
</p><p xmlns="http://www.w3.org/1999/xhtml">
There is a lot more that can be done regarding how you’re playing with the eggs. Using <a xmlns="" href="http://pypi.python.org/pypi/virtualenv" hreflang="en">virtualenv</a> to keep multiple, sane environments and maybe your own cheeseshop where all your eggs can live (see <a xmlns="" href="http://github.com/ask/chishop" hreflang="en">Ask’s Chishop</a>)
</p><p xmlns="http://www.w3.org/1999/xhtml">
I’m very fresh on that field but am very happy seeing that such good tools exist. Please share your experience, I’m looking forward knowing what kind of process is used in the real word out there to.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
La force de PHP est et a été sa facilité de déploiement, on dépose un fichier et c’est parti mon kiki. Merci Apache + mod_php. Scénario pas toujours aussi simple dans les autres environnements d’applications web (si je mets de côté tout ce qui est CGI bien évidemment). Pour avoir bossé dans un environnement Ruby on Rails ces six derniers mois, un serveur fonctionnant sous Passenger est assez simple par rapport à ça. Recherchant toujours comment mettre ceci en place dans le monde Python, voici une approche assez minimaliste (certainement trop) pour déployer une application WSGI sous forme de paquet Python via Paster, Spawning et Fabric.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Ne voulant polluer cet espace-là, merci de regarder les exemples de code dans la zone anglophone. Ils sont également disponible sur <a xmlns="" href="http://gist.github.com/235338" hreflang="en">GitHub</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Si Ruby a les gems, Python a les eggs (bien que certains Python soient ovovivipares) centralisés sur PyPI. Les avantages que je vois à créer un paquet pour son application est tout ce qui vient avec setuptools (et ses alternatives), c’est-à-dire : gestion des dépendances, exclusion des tests (et de leurs dépendances), versions, et certainement séparation en de multiple paquets.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Une fois le fichier setup.py créé, il va s’agir d’écrire un application web Python, ici WSGI mais il y a pas que ça et ça devrait couvrir 98% des besoins.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Ian Bicking a mis au point un système d’outils plus ou moins lié à WSGI nommé Paste qui permet de configurer et lancer une application web via des fichier de configuration INI (quand on est cool on fait du YAML parait-il). Paste requiert qu’on lui fournisse une méthode retournant une application WSGI, cette méthode dite fabrique, reçoit tous les éléments de configuration du fichier .ini. Chose très pratique afin d’avoir divers environnements tel que Ruby on Rails le pratique, comme : développement, test, production. Libre à chacun de faire comme il l’entend.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Le fichier .ini en question définit le paquet Python de nombre application et le serveur web à utiliser, ici Spawning qui a la force de se recharger automatiquement en cas de modification de fichiers détectée.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Travaillant avec un paquet, il est nécessaire de l’installer avant de pouvoir s’en servir. L’installation avec develop crée un lien symbolique où les modifications seront prises en compte sans devoir réinstaller.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Vous devriez pouvoir visualer ce hello world sur le port 8080 de votre machine.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Dernière étape, la plus intéressante peut-être, déployer votre application sur une machine distante, même si distante signifie localhost c’est pour l’exercice.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Si Ruby a Capistrano (et d’autres), Python lui a Fabric qui peut être vu comme un makefile pythonique avec des super pouvoirs lié à SSH.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Le fichier donné ici permet de créer le fichier .egg, de l’envoyer sur l’autre machine (votre serveur) via <code>deploy</code>, puis de le démarrer avec <code>start</code>. Tous les autres <code>deploy</code>’s ne demanderont pas de redémarrage puisque Spawning s’occupe de ça directement. Une fois que vous en avez terminé, un simple stop l’arrêtera. Je trouve judicieux de lancer les applications en tant que simple utilisateur sur un port comme 8080. Il est quand même de bon ton d’avoir un véritable serveur web tel que Apache, <a xmlns="" href="http://www.lighttpd.net/" hreflang="en">Lighty</a> ou Nginx servant de proxy vers votre application et s’occupant de tous les fichiers statiques par la même.
</p><p xmlns="http://www.w3.org/1999/xhtml">
<em>In fine</em>, la solution de l’egg exécuté tel quel est un peu brutale. Je vous invite à vous pencher vers virtualenv et <a xmlns="" href="http://github.com/ask/chishop" hreflang="en">Chishop</a>. Et recherchant toujours une bonne manière de combiner tout ceci, vos solutions m’intéressent.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Bien du plaisir!
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Adaptive layout for the mobile web</title>
      <link>http://yoan.dosimple.ch/blog/2009/10/31</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2009/10/31</guid>
      <pubDate>Sat, 31 Oct 2009 12:37:00 +0100</pubDate>
      <category>CSS iPhone Mobile Opera Webkit</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
One web, is still in the air and we, as web developers, are still hoping that it will be the case. Nowadays, phones are getting better and better and the need of doing a specific version of any website if, as I see it, fading away. When someone tells you: <em>“Hey, I need an iPhone/Android/Pre/Maemo app (or maybe an Opera/Vodafone widget) for my website!”</em> I would try to show her/him that, at a very small cost, a well done website can be adapted to those devices.
</p><p xmlns="http://www.w3.org/1999/xhtml">
If the iPhone marketshare is quite big, other platforms are emerging. The cool side is that they are built on Webkit as well, like: Android or Palm Pre. Less powerful phones might run Opera mini which has also a very good support of web standards. I’ll try to show simple things you can do to give your website a better experience everywhere without building multiple versions of it.
</p><p xmlns="http://www.w3.org/1999/xhtml">
The biggest problem, the width. On the desktop side, it’s commonly assumed that 1024x768 is the standard. This is why the ~960px width layout is so common (take Yahoo!, Facebook, LinkedIn, …). My opinion is that netbooks will gain some marketshare too and it also weight the fact that one size fits all will be outdated in the next years.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Devices might use HVGA 480x320 (iPhone, Pre, HTC Dream) or QVGA 320x240 or maybe bigger or smaller. The iPhone comes with a feature to control the viewport, which might be supported by the others (like <a xmlns="" href="http://dev.opera.com/articles/view/opera-mobile-9-5-the-developer-angle/" hreflang="en">Opera</a>) or not.
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;meta name=viewport
      content="width=320; user-scalable=1;"&gt;</pre><p xmlns="http://www.w3.org/1999/xhtml">
Like <a xmlns="" href="http://www.slideshare.net/glazou/paris-web2009-one-web" hreflang="en">Daniel Glazman said during Paris Web 2009</a>, please don’t prevent the user to scale in/out. This is totally non-standard and there is a standard way of doing that. It’s called media-queries.
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;link href="small.css"
      media="handheld, only screen and (max-device-width: 480px)"
      rel="stylesheet" 
      type="text/css"&gt;</pre><p xmlns="http://www.w3.org/1999/xhtml">
This stylesheet gonna be applied on handheld devices and others with a very narrow screen (smaller than 480px in this case) and it enables to do cool things like :
</p><ul xmlns="http://www.w3.org/1999/xhtml">
    <li>going with a liquid layout instead of a fixed or elastic one;</li>
    <li>linearizing multiple-columns layout (<code>float:none</code>);</li>
    <li>hiding unnecessary stuffs (like you already do in your print stylesheet of course);</li>
    <li>resizing big picture (<code>max-width: 100%</code>);</li>
    <li>making small things bigger, so you can click them more easily (like tiny icons);</li>
    <li>taking into account that there is no <code>:hover</code> state on a touch screen;</li>
    <li>and many more…</li>
</ul><p xmlns="http://www.w3.org/1999/xhtml">
Such small screen cannot take advantages of the two dimensions, like a usual monitor does, so a linear (in the Y-axis of course) layout is preferred.
</p><p xmlns="http://www.w3.org/1999/xhtml">
They are of course many, more issues that can be addressed like the iPhone file-size cache limitation, bandwidth reduction, HTTP calls,… I wouldn’t focus on those until you get an audience worth doing so. If it’s not your target of course.
</p><p xmlns="http://www.w3.org/1999/xhtml">
I won’t throw the baby with the bathwater and native applications are good if you need to do specific things with the device itself or require specific performances. Phones offer, or will offer, access to the address book, the camera, the geo-localization,… Most of those require specific actions which aren’t completely specified/implemented yet, like <a xmlns="" href="http://bondi.omtp.org/" hreflang="en">OMTP Bondi</a>  or <a xmlns="" href="http://dev.w3.org/geo/api/spec-source.html" hreflang="en">W3C</a> itself. 
</p><p xmlns="http://www.w3.org/1999/xhtml">
The best platform to test that is OSX, simply because the iPhone SDK won’t work elsewhere. Testing with the Android emulator or Opera Mini can be done on any platform. Mozilla promised to release soon a version of Fennec targeting the Maemo platform which is already using <a xmlns="" href="http://maemo.nokia.com/features/maemo-browser/" hreflang="en">Gecko</a>. By the way, the <a xmlns="" href="http://maemo.nokia.com/#device-intro" hreflang="en">N900</a> looks awesome! To develop it, simply activate that stylesheet for everyone, so no media-queries.
</p><p xmlns="http://www.w3.org/1999/xhtml">
It very easy to start adapting a website to smaller devices and may even force you to have a better grid structure. Maybe not yet a business advantage, but sooner or later it will.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Un seul web (<em>“One Web”</em>) a été usé et re-usé lors du dernier Paris Web. C’est une idée ou un espoir qui plane depuis toujours il me semble. Avec la démocratisation des appareils nomades permettant de consulter le véritable web (ni WAP, ni i-mode). Le réflexe actuel me semble être : <em>« il faut que je fasse réaliser une application iPhone/Android/Pre (ou un widget Opera/Vodafone) pour mon site »</em>. Dans ce cas, je présenterais ce qu’il est possible de faire avec l’existant, et ce qui nécessiterait une application native.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Si le monde du mobile est une jungle encore plus dense que ce qu’on expérimente avec les navigateurs usuels. Les acteurs principaux se divisent entre Webkit (iPhone, Android, Palm Pre, …) et Opera (avec Opera mini). Des moteurs de rendu connus (entre autres) pour leur support de qualité des standards. Des outils existent pour éviter de produire plusieurs versions d’un même site.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Le pas premier à franchir est qu’il est assumé aujourd’hui que 1024x768 est le minimum syndical. Pour preuve le nombre de sites reposant sur cette largeur là, de manière fixée. L’arrivée des netbooks va, j’espère tendre vers un parc informatique encore plus hétérogène et une fin progression de la taille unique.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Pour revenir à nos moutons, nombre d’appareils ont un écran dit HVGA (demi-VGA, 320x480) ou QVGA (quart-VGA, 320x240). C’est pourquoi vous verrez souvent la ligne suivante :
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;meta name=viewport
      content="width=320; user-scalable=1;"&gt;
</pre><p xmlns="http://www.w3.org/1999/xhtml">
Un élément propriétaire à l’iPhone, qui force la largeur à 320px et dans ce cas autorise le zoom utilisateur. Comme l’a souligné Daniel Glazman lors de <a xmlns="" href="http://www.slideshare.net/glazou/paris-web2009-one-web" hreflang="en">sa présentation (ou devrais-je dire show)</a> en novembre dernier, désactiver cette fonctionnalité est un non-sens. D’autres navigateurs peuvent supporter cet attribut là, je pense notamment à <a xmlns="" href="http://dev.opera.com/articles/view/opera-mobile-9-5-the-developer-angle/" hreflang="en">Opera</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Mais, la boîte-à-outils du W3C n’est pas en reste, avec les media-queries qui permettent de cibler un navigateur selon des spécification techniques :
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;link href="small.css"
      media="handheld, only screen and (max-device-width: 480px)"
      rel="stylesheet" 
      type="text/css"&gt;</pre><p xmlns="http://www.w3.org/1999/xhtml">
Comme dans ce cas, la largeur maximale en pixels de l’appareil. Donc si l’appareil est plus petit que 480px de large, la feuille de style est appliquée. Feuille qui permet de faire tout un tas de choses intéressantes :
</p><ul xmlns="http://www.w3.org/1999/xhtml">
    <li>passer à une mise en forme fluide, et non plus fixée ou élastique ;</li>
    <li>linéariser des colonnes ;</li>
    <li>masquer ce qui sert de décoration</li>
    <li>limiter la taille maximale des images, par exemple ;</li>
    <li>agrandir certains éléments pour pouvoir les sélectionner avec de gros doigts (sur un petit écran) ;</li>
    <li>prendre en compte qu’il n’y a pas d’effet de survol sur un écran tactile ;</li>
    <li>et tout un tas d’autres…</li>
</ul><p xmlns="http://www.w3.org/1999/xhtml">
Il y a plusieurs autres points à prendre en considération si l’audience se servant d’appareil nomade est  assez importante. Une version adaptée, ne saura certainement pas contenter tous les usagers. C’est à mes yeux un investissement faible et qui amène forcément un plus qualitatif, passer de deux dimensions à une seule implique que la logique de base soit bonne.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Pour ne pas jeter le bébé avec l’eau du bain, il y a un intérêt à l’option application native, pour ne serait-ce qu’au niveau des performances. Plus spécialement dès qu’il s’agit d’intéragir avec l’appareil lui-même, comme consulter le carnet d’adresse, l’appareil photo ou le GPS. Des solutions au sein du navigateur arrivent tant via le <a xmlns="" href="http://dev.w3.org/geo/api/spec-source.html" hreflang="en">W3C</a> qu’<a xmlns="" href="http://bondi.omtp.org/" hreflang="en">OMTP Bondi</a> pour citer ceux que je connaisse.
</p><p xmlns="http://www.w3.org/1999/xhtml">
En matière de test, tout est testable depuis partout, sauf pour l’iPhone où le SDK nécessite le système d’exploitation OS X. L’émulateur Android offre différentes géométries d’écran, ce qui est intéressant. Opera mini est disponible en ligne. Pour parler un peu de Mozilla, Fennec devrait arriver pour le N900 (Maemo utilisant déjà Gecko) d’ici peu. Sinon, en activant la feuille de style comme une autre permet de faire un premier test également. Il y a de quoi s’amuser à améliorer l’expérience utilisateur de nos sites sur ces appareils là. C’est vraiment ludique à faire, même en tant que non-possesseur de ce type d’appareils là.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Working on the edge</title>
      <link>http://yoan.dosimple.ch/blog/2009/09/24</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2009/09/24</guid>
      <pubDate>Thu, 24 Sep 2009 23:05:00 +0200</pubDate>
      <category>Rails Ruby Work</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
At work we worked (it’s now over) quite hard to migrate our codebase to take advantage of the latest features and bug fixes of the underlying framework and libraries (in our case Ruby on Rails). It’s hard because of the decisions that were made upfront by the consulting company who started it.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Let’s start with the background. The development started in 2008 and they picked Rails 1.2.x when Rails 2.0.x existed for almost one year already. This design decision might have been motivated by the fact that some libraries weren’t yet ported to the latest version but still. PDF-writer instead of Prawn when it was known that the later gonna <a xmlns="" href="http://www.infoq.com/news/2008/08/ruby-pdf-generation-prawn" hreflang="en">become the one maintained</a> and I can continue with other examples.
</p><p xmlns="http://www.w3.org/1999/xhtml">
This recalls me a story of a huge homemade CMS that had to run inside an emulator for the OS running an utterly old version of Perl because they were no budget to maintain it. When you get there, it’s obviously too late.
</p><p xmlns="http://www.w3.org/1999/xhtml">
I wanna make an analogy with the (most popular) operating system out there:
</p><ul xmlns="http://www.w3.org/1999/xhtml">
<li>I’m using a GNU/Linux flavoured distribution (the very modular one that compiles everything) so I can update it as often as I want (usually once a day) and when something break it’s usually one of them that is easy to identify and most of the time easy to fix too.</li>
<li>I also use OSX at work and you can feel the upgrade fear. One medium-sized upgrade with often no possible rollback. It toke one week-end  to my workmate to get his dev environment running again. During the last upgrade I had to reinstall everything coming from macports and most of the Ruby gems.</li>
<li>And last but not least, Microsoft Windows. How many Windows 98, 2000 are out there? Many users of IE6 are stuck to it because there are stuck to a particular version of the OS underneath too. I dunno the cost of installing a new version of Microsoft Windows into a company but it must be big (if you take into account the time required).</li>
</ul><p xmlns="http://www.w3.org/1999/xhtml">
Web development nowadays is closer to the Linux (and some other unices) distribution philosophy than the two others. Your application is using a bunch of libraries, maybe a framework. They usually have a website, the open source ones a bug tracker, feed of the changes, mailing list and maybe hosted somewhere you can interact with (like github, bitbucket, google code, ...) You can keep an eye on the changes, update them easily.
</p><pre xmlns="http://www.w3.org/1999/xhtml"># Ruby
gem update
# Python
yolk -U
easy_install -U xxx</pre><p xmlns="http://www.w3.org/1999/xhtml">
I’ll not give any details about CPAN (Perl) or PEAR (PHP) since I’ve never used them.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Software development, in the web field at least because it’s what I know the most, is also subject to entropy and requires some energy to keep everything clean. Keep your working environment clean, like a cook has to clean his entire kitchen once in a while. If project manager should do regular bug triage, developer can do, for example <code>TODO</code>/<code>FIXME</code> cleanup sessions.
</p><p xmlns="http://www.w3.org/1999/xhtml">
A trivial advice: when you start a development that will last a couple of months, go with the most recent version or why not the bleeding-edge one (often called <em>trunk</em>, <em>tip</em>, <em>head</em>, …) if it might be stable when you’ll be done.
</p><p xmlns="http://www.w3.org/1999/xhtml">
I’m wondering if a company that doesn’t have the resources to maintain a piece of code shouldn’t open source it to take advantage of a community-to-build. But this has a cost too.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
L’enfer des mises-à-jour, des migrations, des changements de version. Voilà ce qui m’occupe depuis quelques temps déjà. Ça ne se passe pas sans douleur, ni surprise ou questionnement. J’aimerais simplement tenter de sensibiliser à quelques choix simples pouvant être fait.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Un peu d’histoire sur le cas qui nous intéresse ici, un passage de Rails 1.2 à la dernière version 2.3, soit grosso modo 2 ans d’écart, d’améliorations, d’ajouts ou de suppressions de fonctionnalités. 2 ans qui paraissent un peu bête quand le site n’a — lui, dans sa version actuelle — qu’une année. Ce qui est peut-être expliquable en se disant que les outils annexes (telles que les bibliothèques) n’avait pas encore eux été adapté pour supporter la dernière version.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Autre exemple, plus ancien, est un CMS qui devait tourner via un émulateur car la version du système d’exploitation (BSD) n’était plus supportée. Quand ce stade là est atteint, c’est qu’il est généralement trop tard pour agir car les autres solutions ont déjà été écartées.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Pour amener l’idée finale, qui est de toujours tenter de suivre les versions récentes (ou actuelles) j’aimerais faire un parallèle avec les systèmes d’exploitation (ou distributions) :
</p><ul xmlns="http://www.w3.org/1999/xhtml">
<li>J’utilise principalement GNU/Linux et c’est un bonheur de ce côté là puisque tout est généralement orchestré par le système de paquets (les apt, yum, portage, pacman, …). Au final, mon système est mis à jour régulièrement, quand je le souhaite et il est possible de revenir en arrière, corrigé rapidement en cas de problème.</li>
<li>OSX qui a un système à la Windows Update mais offre (lisez vend) régulièrement des mises à jour comprenant des changements plus importants. Bien que de tailles raisonnables elles ne sont pas toujours sans douleur et généralement sans retour en arrière (simple).</li>
<li>et le dernier Microsoft Windows, qui traine toujours des casseroles fonctionnant sous des versions vieilles d’une bonne décennie. Des systèmes verouillés dans le temps car une mise à jour est trop coûteuse, impossible ou jugée inutile.</li>
</ul><p xmlns="http://www.w3.org/1999/xhtml">
Quand mettre à jour signifie réinstallation avec ou non achat de nouveau matériel, j’ai peu d’espoir que ça puisse suivre rapidement. Point prouvé avec les différentes politiques de mise à jour des navigateurs d’ailleurs.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Le développement web est assez proche d’une distribution Linux, généralement le serveur fonctionne sur cette technologie d’ailleurs. Une application va fonctionner se reposant sur un ensemble de bibliothèques, dans le meilleur des cas open source, dont il est possible de suivre les évolutions et les appliquer. La simplicité d’appliquer une petite mise à jour, au fur comparée a un gros changement est à mon sens d’une logique sans faille. La première étant satisfaisante et la seconde ressemble plus à une corvée.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Dernier petit conseil, au début d’une nouvelle application, n’hésitez pas à opter pour la version de développement, il y a fort à parier que celle-ci se stabilise d’ici à ce que vous aillez terminé. S’il y a effectivement un gain par rapport à celle dite stable.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Je me demande dans quelle mesure une application ne pouvant plus être maintenue peut y remédier en tentant d’ouvrir son code.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>XML with Padding</title>
      <link>http://yoan.dosimple.ch/blog/2009/08/17</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2009/08/17</guid>
      <pubDate>Mon, 17 Aug 2009 17:05:00 +0200</pubDate>
      <category>E4X JavaScript Python</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
Last week we had a small arguing on #openweb about whether JSON is better than XML. The only reason to me JSON is really beating XML is called JSONP (JSON with Padding). It’s a way to get data from a different domain using JavaScript. That data is formatted in JSON (which stands for JavaScript Object Notation). I’ll show how to send data formatted in XML which the huge drawback to only work on Gecko (because it relies on a technology that only it supports: <a xmlns="" href="https://developer.mozilla.org/En/E4X" hreflang="en">E4X</a>).
</p><p xmlns="http://www.w3.org/1999/xhtml">
But as we are forced to use Gecko we should simple go for the <a xmlns="" href="https://developer.mozilla.org/En/HTTP_Access_Control" hreflang="en">Cross-domain XmlHTTPRequest</a>, it’s simpler and safer.
</p><p xmlns="http://www.w3.org/1999/xhtml">
JSONP works by appending a script to the page that will call a function we gave it with the data we expect:
</p><pre xmlns="http://www.w3.org/1999/xhtml">callback({hello:"World!"});</pre><p xmlns="http://www.w3.org/1999/xhtml">
for example. It’s totally unsafe and you have to really trust that third party. XMLP relies on the fact that E4X makes XML first citizen, like <code>RegExp</code>, <code>Array</code> or any other native type.
</p><pre xmlns="http://www.w3.org/1999/xhtml">var a = &lt;root&gt;I’m the root&lt;/root&gt;;</pre><p xmlns="http://www.w3.org/1999/xhtml">
So, XMLP might look like:
</p><pre xmlns="http://www.w3.org/1999/xhtml">callback(&lt;hello&gt;World!&lt;/hello&gt;);</pre><p xmlns="http://www.w3.org/1999/xhtml">
On Gecko (reading Firefox and bros), E4X can be enabled by adding <code>eax=1</code> to the type:
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;script type="text/javascript;e4x=1" …&gt;&lt;/script&gt;</pre><p xmlns="http://www.w3.org/1999/xhtml">
E4X is quite interesting to play with. Unfortunately Gecko and Flash are the only two platforms where you can use it. By Gecko I mean SpiderMonkey and Rhino (the two JavaScript engines Mozilla branded).
</p><p xmlns="http://www.w3.org/1999/xhtml">
Grab this very <a xmlns="" href="http://yoan.dosimple.ch/blog/2009/08/17/xmlp.py">basic example application for Python</a>.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Voici ma première invention inutile; même d’autres y ont pensé avant <a xmlns="" href="http://blogs.nitobi.com/dave/2006/01/27/xml-with-padding/" hreflang="en">moi</a> pas d’illusion sur ce fait là. L’idée est de transposer le fonctionnement de <a xmlns="" href="http://json.org/" hreflang="en">JSON</a>P à XML. JSONP est le moyen d’importer des données venant d’ailleurs et de les récupérer et de les traiter chez soi, comme on l’entend. Les célèbres MashUps, aka combinaisons de différentes sources de données ou outils en un nouvel élément se servent souvent de JSONP (via <a xmlns="" href="http://pipes.yahoo.com/">Y! Pipes</a> ou <a xmlns="" href="http://developer.yahoo.com/yql/" hreflang="en">YQL</a> par exemple).
</p><p xmlns="http://www.w3.org/1999/xhtml">
Dans un long débat concernant le bien fondé d’un JSON vs XML; JSONP me semblait le seul élément qui offrait un avantage intéressant à JSON. En tant compte de tous les problèmes de sécurité. JSONP ressemble à ceci:
</p><pre xmlns="http://www.w3.org/1999/xhtml">maFonction({message: "Salut !"});</pre><p xmlns="http://www.w3.org/1999/xhtml">
Ceci est fournit par un autre serveur est est inclu via une conventionnelle balise scripte. XMLP repose sur le fait que grâce à <a xmlns="" href="https://developer.mozilla.org/En/E4X" hreflang="en">E4X (ECMAScript for XML)</a>, XML devient un élément natif de JavaScript.
</p><pre xmlns="http://www.w3.org/1999/xhtml">var doc = &lt;racine&gt;Salut !&lt;/racine&gt;;</pre><p xmlns="http://www.w3.org/1999/xhtml">
Donc, il est également possible d’envoyer ça à sa fonction dite de callback :
</p><pre xmlns="http://www.w3.org/1999/xhtml">maFonction(&lt;racine&gt;Salut !&lt;/racine&gt;);</pre><p xmlns="http://www.w3.org/1999/xhtml">
Si c’est assez brillant, le problème réside dans le fait que ça n’est uniquement supporté par Spidermonkey (et Rhino); le moteur JavaScript de Firefox ainsi que les produits Flash.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Petite astuce pour activer E4X, spécifier via le type du scripte.
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;script type="text/javascript;e4x=1" …&gt;&lt;/script&gt;</pre><p xmlns="http://www.w3.org/1999/xhtml">
Firefox supportant dans les versions récentes <a xmlns="" href="https://developer.mozilla.org/En/HTTP_Access_Control" hreflang="en">les requêtes sur d’autres domaines</a>, il est bien plus viable de passer par XmlHTTPRequest.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Bref, c’était un petit amusement, que je vous invite à essayer vous même: <a xmlns="" href="http://yoan.dosimple.ch/blog/2009/08/17/xmlp.py">xmlp.py</a>.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Live statistics for your website</title>
      <link>http://yoan.dosimple.ch/blog/2009/07/18</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2009/07/18</guid>
      <pubDate>Sat, 18 Jul 2009 17:05:00 +0200</pubDate>
      <category>GoogleAnalytics Memcached Python Ruby</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
If Google Analytics (formerly Urchin) has become one of the most popular tracking systems, it fails at being live because of its architecture. You only get valid data the day after which is the default view anyways. I tried to make something to improve the actual solution we are using at work.
</p><p xmlns="http://www.w3.org/1999/xhtml">
What we do have <a xmlns="" href="http://www.eboutic.ch/" hreflang="de">at work</a> is a basic session counter. It helps us not pushing a release when a lot of people are surfing the website even it has been easier since we switched from Mongrel to Passenger. From a simple number, like <em>“280 sessions”</em> I’d try to move that to the next level and having a view of the actual usage.
</p><p xmlns="http://www.w3.org/1999/xhtml">
The idea is to count views and to store that into <a xmlns="" href="http://www.danga.com/memcached/" hreflang="en">memcached</a> using the current time as a key and putting a timeout of the length of the needed graph.
</p><pre xmlns="http://www.w3.org/1999/xhtml"><i># first visit</i>
memcache.add(now, 1, 3600)

<i># next visits</i>
memcache.incr(now)
</pre><p xmlns="http://www.w3.org/1999/xhtml">
And to build the graph, you get all the values from a set of keys at once and then use Google Chart is used to build a nifty view.
</p><p xmlns="http://www.w3.org/1999/xhtml" style="text-align:center;">
    <img src="/blog/2009/07/18/preview.png" alt="Stats for the last hour (preview)"/><br/>
<a xmlns="" href="http://yoan.dosimple.ch/blog/2009/07/18/full.png">Stats of the last hour charted</a> by <a xmlns="" href="http://code.google.com/apis/chart/">Google Chart</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
This is a <a xmlns="" href="http://rack.rubyforge.org/" hreflang="en">Rack</a> (or a <a xmlns="" href="http://wsgi.org/" hreflang="en">WSGI</a>) middleware so can fit into your application very easily. Get the source code that contains an example:
</p><ul xmlns="http://www.w3.org/1999/xhtml">
<li><a xmlns="" href="http://yoan.dosimple.ch/blog/2009/07/18/livestats.ru">Ruby</a> (<code>thin -R livestats.ru start</code>)</li>
<li><a xmlns="" href="http://yoan.dosimple.ch/blog/2009/07/18/livestats.py">Python</a> (<code>python livestats.py</code> or <code>spawn livestats.application</code>)</li>
</ul><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Si Google Analytics semble être devenu l’outil de statistiques le plus répandu pour les modestes bourses, il y a un point où il pèche : avoir des données live. C’est dû à l’architecture choisie par Urchin (à l’époque) j’imagine. Architecture qui sert une fonction précise et justement pas celle d’être instantanée.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Le <a xmlns="" href="http://www.eboutic.ch/" hreflang="fr">site internet</a> sur lequel je suis employé utilise simplement un compteur du nombre de sessions en cours afin de déterminé si c’est un moment chaud ou normal face à une mise à jour devant être faite. Le but étant bien sûr de minimaliser les coupures. L’idée ici est de donner une information instantanée qui n’est ni pérenne ni représentative du nombre de personnes physiques utilisant le site actuellement. Pour info, ça n’est pas utilisé actuellement, c’était simplement pour mentionné la source d’inspiration et le contexte.
</p><p xmlns="http://www.w3.org/1999/xhtml">
L’idée est de stocker des compteurs dans <a xmlns="" href="http://www.danga.com/memcached/" hreflang="en">memcached</a> pour un temps donné et de laisser <a xmlns="" href="http://code.google.com/apis/chart/">Google Chart</a> faire le travail de mise en forme.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Le code est à votre disposition :
</p><ul xmlns="http://www.w3.org/1999/xhtml">
<li><a xmlns="" href="http://yoan.dosimple.ch/blog/2009/07/18/livestats.ru">Ruby</a> (<a xmlns="" href="http://rack.rubyforge.org/" hreflang="en">Rack</a>)</li>
<li><a xmlns="" href="http://yoan.dosimple.ch/blog/2009/07/18/livestats.py">Python</a> (<a xmlns="" href="http://wsgi.org/" hreflang="en">WSGI</a>)</li>
</ul></blockquote>]]></description>
    </item>
    <item>
      <title>Email interface for Twitpic</title>
      <link>http://yoan.dosimple.ch/blog/2009/06/26</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2009/06/26</guid>
      <pubDate>Fri, 26 Jun 2009 17:05:00 +0200</pubDate>
      <category>Email SMTP Python Twisted TX</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
The <a xmlns="" href="http://lamsonproject.org/" hreflang="en">Lamson Project</a> emerged recently, but dealing with emails as always been around. Sending emails can be a pain for other reasons than receiving email is one too. Let’s focus on the second one with a simple demo that posts a picture to <a xmlns="" href="http://twitpic.com/api.do" hreflang="en">TwitPic</a> from an email using <a xmlns="" href="http://twistedmatrix.com/" hreflang="en">Twisted</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Disclaimer, I haven’t tested <em>Lamson</em> but feels more confident to go with a solution built on top of Twisted then another one redoing most of the job using plain <a xmlns="" href="http://docs.python.org/library/asyncore.html" hreflang="en">asyncore</a> and <a xmlns="" href="http://docs.python.org/library/threading.html" hreflang="en">threads</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
We will start by using <a xmlns="" href="https://launchpad.net/tx/txmailserver" hreflang="en">txmailserver</a> originally built by <a xmlns="" href="http://oubiwann.blogspot.com/2009/01/twisted-mail-server-conclusion.html" hreflang="en">Duncan McGreggor</a>, a set of tools to set up a basic STMP server, with POP3 support.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Read the file <a xmlns="" href="http://yoan.dosimple.ch/blog/2009/06/26/server.tac">server.tac</a> to see all the boiler plate, I’ll show the interesting parts.
</p><pre xmlns="http://www.w3.org/1999/xhtml">def twitpic_it(dest, message):
 pass # see bellow

domains = {
 "twitpicit.org": [
  Script(r"[a-zA-Z_0-9\-\.]+\+.+",
         twitpic_it)
 ]
}</pre><p xmlns="http://www.w3.org/1999/xhtml">
It’ll accept any email users that look like: <code>me+mypassword@twitpicit.org</code> and call the <code>twitpic_it</code> function. From there we can do whatever we want. No more details on the email treatment.
</p><pre xmlns="http://www.w3.org/1999/xhtml">def twitpic_it(dest, message):
 username, password = dest.local.split("+", 1)
 
 <i># finding the part which is a picture</i>
 <i># and building a temporary file with it</i>
 file = file_from_message(message)

 if file is not None:
  datagen, headers = <a xmlns="" href="http://atlee.ca/software/poster/poster.encode.html#poster.encode.multipart_encode" hreflang="en">multipart_encode</a>({
   "username": username,
   "password": password,
   "message": message["Subject"],
   "media": file
  })

  request = urllib2.Request(
   "http://twitpic.com/api/uploadAndPost",
   "".join(datagen),
   headers)

  file.close()

  urllib2.urlopen(request).read()</pre><p xmlns="http://www.w3.org/1999/xhtml">
There you go, you’re able to <em>twitpic</em> everything you like from any email client. After you’ve set up that on one of your domain of course or you can try it locally using a simplistic Python script: <a xmlns="" href="http://yoan.dosimple.ch/blog/2009/06/26/test.py">test.py</a>.
</p><pre xmlns="http://www.w3.org/1999/xhtml">$ twistd -ny <a xmlns="" href="http://yoan.dosimple.ch/blog/2009/06/26/server.tac">server.tac</a></pre><p xmlns="http://www.w3.org/1999/xhtml">
in a different shell:
</p><pre xmlns="http://www.w3.org/1999/xhtml">$ python <a xmlns="" href="http://yoan.dosimple.ch/blog/2009/06/26/test.py">test.py</a> mypicture.png My message</pre><p xmlns="http://www.w3.org/1999/xhtml">
The server should display the response from Twitpic. Of course this is purely overkill if you can directly use the API.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Email is still an interesting interface for people that aren’t techie at all. For people that sits behind a desk with only that as an interface to the outside world because the IT service decided that you shouldn’t spend your day playing on Facebook or because you are <a xmlns="" href="http://lwn.net/Articles/262570/">Richard M. Stallman (RMS) himself</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Most of the time a bad usage of emails is made, like answering leads to nothing (the infamous noreply), of you have to visit it inside a browser to do something. Don’t neglect it as a tool that most of the people understand and know how to use it. It means they <a xmlns="" href="http://www.sensible.com/buythebook.html" hreflang="en" title="Don&#x2019;t make me think, the book">don’t have to think</a> too much in order to use it.
</p><p xmlns="http://www.w3.org/1999/xhtml">
The code is on <a xmlns="" href="https://code.launchpad.net/~greut/txmailserver/imap4">Launchpad</a>.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Email premier usage popularisant le web reste une bête difficile à dompter, en raison de son usage publicitaire intensif, mais a le potentiel d’être un outil de choix pour la simple et bonne raison qu’il est connu de toutes et tous et n’est que très rarement bloqué par un service informatique faisant du zèle (pour ceux qui intéragissent avec le web essentiellement depuis leur place de travail).
</p><p xmlns="http://www.w3.org/1999/xhtml">
En exemple un <a xmlns="" href="http://yoan.dosimple.ch/blog/2009/06/26/server.tac">mini serveur SMTP</a> ne fonctionnant qu’en mode réception — rien ne vaudra jamais un véritable <a xmlns="" href="http://fr.wikipedia.org/wiki/Mail_Transfer_Agent" hreflang="en">MTA</a> pour fonctionner en mode <i>relay</i> (émission), type <a xmlns="" href="http://www.postfix.org/">postfix</a> ­— qui va poster l’image sur Twitpic avec le texte donné en titre.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Le code est écrit en Python et repose sur <a xmlns="" href="http://twistedmatrix.com/" hreflang="en">Twisted</a>, un ensemble d’outil permettant de programmer de manière évènementielle et contenant bon nombre de protocoles supportés (tel SMTP et POP3, dans notre cas). Le code de base provient du projet <a xmlns="" href="https://launchpad.net/tx/txmailserver" hreflang="en">txmailserver</a> qui a pour but d’offrir un serveur SMTP/POP3 minimaliste.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Comme vous pouvez le voir dans ce script fonctionnant comme serveur permet de passer les adresses reçues à une fonction. Ensuite, libre à votre imagination créative d’y faire ce que bon vous semble. Je ne connais pas <a xmlns="" href="http://lamsonproject.org/" hreflang="en">Lamson</a> qui a pour but de servir de boîte à outils pour ce type d’applications là.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Trouvez le code sur <a xmlns="" href="https://code.launchpad.net/~greut/txmailserver/imap4" hreflang="en">Launchpad</a>.
</p></blockquote>]]></description>
    </item>
    <item>
      <title>Messages powered web applications</title>
      <link>http://yoan.dosimple.ch/blog/2009/05/10</link>
      <guid isPermaLink="true">http://yoan.dosimple.ch/blog/2009/05/10</guid>
      <pubDate>Sun, 10 May 2009 17:05:00 +0200</pubDate>
      <category>AMQP JavaScript Python RabbitMQ</category>
      <description><![CDATA[<p xmlns="http://www.w3.org/1999/xhtml">
The web is made of messages, e-mail is the first class citizen of them. Instant messaging protocols (like the beloved XMPP) and now Twitter and every twitter-like applications are collecting and sending back tons of messages. Let’s see how this concept can be applied and becoming very useful at a smaller scale too.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Before going further, <a xmlns="" href="http://www.hackdiary.com/" hreflang="en">Matt Biddulph</a> (CTO of <a xmlns="" href="http://www.dopplr.com" hreflang="en">Dopplr</a>) made a very interesting presentation explaining how Dopplr is using messages that transit between the different parts of the application. Take a look at it! <a xmlns="" href="http://www.slideshare.net/carsonified/dopplr-its-made-of-messages-matt-biddulph-presentation">Dopplr: It's made of messages - Matt Biddulph</a>
</p><p xmlns="http://www.w3.org/1999/xhtml">
How messages can help your web application to become better? Like every good manager do, by delegating. Instead of doing everything yourself, let other people doing that for you. The drawback is that you’ll have to wait on that person to do his job, the good ones are that you can quickly answering your customer (sending back a HTML page in our case).
</p><p xmlns="http://www.w3.org/1999/xhtml">
I wrote a simple application called <a xmlns="" href="http://bitbucket.org/greut/up/" hreflang="en">up!</a> that is an image uploader. The cool thing about this image uploader is that, like Flickr for example, once the pictures are uploaded the application tells you that the thumbnails are currently processed and that you’ll very soon get them without telling anything before its done (which is rude, but common)
</p><p xmlns="http://www.w3.org/1999/xhtml">
Let’s dive with the image upload.
</p><p xmlns="http://www.w3.org/1999/xhtml" style="text-align:center">
    <img src="/blog/2009/05/10/rabbit_0.png" alt="Upload schema"/>
</p><p xmlns="http://www.w3.org/1999/xhtml">
When John uploads his picture, the file is saved into a temporary directory and a message of this kind is sent to a queue called resize.
</p><pre xmlns="http://www.w3.org/1999/xhtml">
("/tmp/foobar.jpg", "jpeg")
</pre><p xmlns="http://www.w3.org/1999/xhtml">
And respond directly with a HTML page containing a placeholder for the thumbnail.
</p><pre xmlns="http://www.w3.org/1999/xhtml">&lt;p id="preview"&gt;
 &lt;span&gt;foobar.jpg&lt;/span&gt; sent.
&lt;/p&gt;
&lt;p id="loading"&gt;&lt;em&gt;
 Please wait for the preview
 to be generated.
&lt;/em&gt;&lt;/p&gt;</pre><p xmlns="http://www.w3.org/1999/xhtml">
Now, the client will try to obtain the expected thumbnails.
</p><p xmlns="http://www.w3.org/1999/xhtml" style="text-align:center">
    <img src="/blog/2009/05/10/rabbit_1.png" alt="Message passing schema"/>
</p><p xmlns="http://www.w3.org/1999/xhtml">
On the client-side a JavaScript code will ping that expecte picture every 2 seconds as long as the server doesn’t find it and therefor answers with an error 404.
</p><p xmlns="http://www.w3.org/1999/xhtml">
During that time, a consumer (a different process, independant from the web server) will get that message, resize the picture in 3 different sizes and put them at the right place. The arrow that goes back to the queue is a message acknowledgement saying that everything went find and that the message can be removed from the queue. The goal is to not lose any messages, if possible.
</p><p xmlns="http://www.w3.org/1999/xhtml" style="text-align:center">
    <img src="/blog/2009/05/10/rabbit_2.png" alt="Thumbnails are generated schema"/>
</p><p xmlns="http://www.w3.org/1999/xhtml">
Once the thumbnails are available, the page displays the picture and the polling is stopped.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Different messaging mecanisms exist, some of them are very simple, like <a xmlns="" href="http://stomp.codehaus.org/" hreflang="en">STOMP</a>, but most of them are transcient only. It means no persistancy, if nobody listens; the messages are lost. Because shit happens, I prefer having some kind of persistency and acknowledgement that a message was well processed. Persistance means slowliness too. For that, this demo uses <a xmlns="" href="http://www.rabbitmq.com/" hreflang="en">RabbitMQ</a> and the <a xmlns="" href="http://www.amqp.org/" hreflang="en">AMQP</a> protocol. The first one is powered by Erlang and both of them are open source. Installing RabbitMQ is as simple as (once downloaded and extracted): <code>make run</code>. Learn more about RabbitMQ reading: <a xmlns="" href="http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/" hreflang="en">Rabbits and warrens</a>.
</p><p xmlns="http://www.w3.org/1999/xhtml">
As libraries, it uses both <a xmlns="" href="https://launchpad.net/txamqp" hreflang="en">txamqp</a> (<em>tx</em> stands for <a xmlns="" href="http://twistedmatrix.com/trac/" hreflang="en">twisted matrix</a>) and <a xmlns="" href="http://pypi.python.org/pypi/amqplib" hreflang="en">amqp-lib</a>. I find <em>amqp-lib</em> handy for the client side, to just send a message and prefer <em>twisted matrix</em> for a server that has to live (if possible) for ever and without causing too many trouble. Using only <em>amqp-lib</em> is of course possible.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Resizing image is one use case, maybe not the best one. In another application, I’m also using a queue for sending e-mail notifications, or it could be IM notification (AMQP instead of XML-RPC in my <a xmlns="" href="http://yoan.dosimple.ch/blog/2008/02/28/" hreflang="en">twootr article</a> for example), ... Separating them from the web server logic as the great advantage that you can tune both of them separately, instanciate more processes to handle image resizing the one you have have too much work without affecting anyone else. Small pieces of software collaborating together.
</p><p xmlns="http://www.w3.org/1999/xhtml">
I’ve read once, that once you’ve gone in that path, you cannot go back. You’ve been warned. I think that big monolithics web apps aren’t agile enough those days where data are growing bigger and data are going faster to many people, mediums and third-parties.
</p><p xmlns="http://www.w3.org/1999/xhtml">
<a xmlns="" href="http://bitbucket.org/greut/up/" hreflang="en">Download it from bitbucket</a> and feel free to hack it or to send me any questions.
</p><blockquote><p xmlns="http://www.w3.org/1999/xhtml">
Envoyer des messages est le cœur d’Internet. Ça a commencé par les courriels (e-mails), puis les messageries instantanées (dont le fameux XMPP) et à l’heure actuelle, Twitter et autres confrères brassent une quantitée impressionnante de petits messages devant être distribués à un grand nombre de destinataires de manière (quasi-)instantanée. Cet article illustre comment l’usage d’une architecture à base de messages peut être bénéfique à une application web.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Avant tout, je vous invite à prendre connaissance de la présentation donnée par Matt Biddulph (CTO de Dopplr) concernant l’architecture qui a été adoptée dans le cadre de ce projet. C’est tout simplement très instructif. <a xmlns="" href="http://www.slideshare.net/carsonified/dopplr-its-made-of-messages-matt-biddulph-presentation">Dopplr: It's made of messages - Matt Biddulph</a>
</p><p xmlns="http://www.w3.org/1999/xhtml">
Comme vous pouvez le voir dans la partie anglophone, qui est joliment illustrée d’ailleurs, le but a été de réaliser un système d’envoi d’images qui va déléguer le traitement des images à un tier. Le serveur web peut ainsi répondre directement informant que le fichier a été envoyé et que les miniatures seront très promptement disponible sans avoir à le faire lui-même.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Un message a été envoyé dans une queue de messages, et va être distribué à une petite application dont le but est juste de redimensionner l’image en (dans ce cas) 3 miniatures. En parallèle, un petit bout de JavaScript va tenter d’accèder aux fichiers devant être produits, à intervale régulier (ici 2 secs), jusqu’à ce que ça réussisse et qu’il soit possible d’afficher le contenu à l’utilisateur.
</p><p xmlns="http://www.w3.org/1999/xhtml">
De prime abord, l’avantage de ce mic-mac n’est pas forcément clair, maintenant imaginez que ceci soit fait par le serveur web directement, qui a pour, presque unique fonction, de servir un maximum de monde le plus rapidement possible. Redimensionner une image implique d’ouvrir un fichier parfois volumineux pour en créer un autre un peu moins volumineux. Ça rime avec mémoire. Et si un serveur web qui sert 50 requêtes simultanément ouvre 50 fichiers JPEG de quelque Mo chacun, ça peut être coriace pour lui, et surtout pénible pour les autres utilisateurs qui aimeraient bien envoyer leurs images mais ne peuvent pas accèder au serveur car il est raz-la-gorge.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Déléguer signifie avoir les mains libres pour faire autre chose, signifie également que si ça ne suit pas de leur côté, il est envisageable d’allouer plus de ressources à cette tâche-là. Et bien sûr, découpler un problème en de multiples tâches réduit un gros problème en plusieurs plus petits problèmes. Dans ce cas-ci c’est tout simplement le bon vieux problème du producteur / consommateur.
</p><p xmlns="http://www.w3.org/1999/xhtml">
Le code se compose d’un peu de Python, tout simplement WSGI, utilisant WebOb, AMQP-lib (pour le producteur) et txAMQP (pour le consommateur). AMQP est un protocole libre et qui possède notamment un client écrit en Erlang nommé RabbitMQ, libre lui aussi. L’avantage de ce dernier est qu’il est capable de gérer des listes persistantes avec confirmation de lecture. Ce qui manque souvent dans d’autres protocoles plus simples, comme STOMP. Trouvez-le et faites-en ce que vous voulez sur <a xmlns="" href="http://www.bitbucket.org/greut/up" hreflang="en">mon compte Bitbucket</a>
</p><p xmlns="http://www.w3.org/1999/xhtml">
L’usage d’AMQP n’est pas forcément facile à prendre en main, tout simplement car les possibilités offertes sont très vastes mais étonnamment efficaces. Il est, par exemple, très simple qu’un message soit dispatchés vers plusieurs consommateurs différents sans avoir à envoyer son message plusieurs fois. Donc de découpler les producteurs des consommateurs, mais c’est une autre histoire qui est très bien documentée dans cet article là : <a xmlns="" href="http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/" hreflang="en">Rabbits and warrens</a>.
</p></blockquote>]]></description>
    </item>
  </channel>
</rss>
