<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bloc-notes de Tristan</title>
	<atom:link href="http://blog.deolen.fr/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.deolen.fr</link>
	<description>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</description>
	<lastBuildDate>Fri, 03 Jul 2009 17:40:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Comment être notifié par mail lors d&#8217;erreurs Symfony</title>
		<link>http://blog.deolen.fr/2009/07/03/comment-etre-notifie-par-mail-lors-derreurs-symfony/</link>
		<comments>http://blog.deolen.fr/2009/07/03/comment-etre-notifie-par-mail-lors-derreurs-symfony/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 17:40:12 +0000</pubDate>
		<dc:creator>Tristan</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[hoptoad]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.deolen.fr/?p=180</guid>
		<description><![CDATA[Note: Cet article a été initialement diffusé sur le blog de Clever Age.

Symfony fournit un mécanisme de journaux permettant de tracer toute sorte de messages, en leur affectant un niveau de criticité (info, warning, err, …). Ainsi, lorsque l’on constate un comportement anormal, on peut aller voir dans les logs les messages nous permettant de [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note: Cet article a été initialement diffusé sur le <a href="http://www.clever-age.com/veille/blog/comment-etre-notifie-par-mail-lors-d-erreurs-symfony.html">blog de Clever Age</a></strong>.</p>
<p><img class="alignleft size-full wp-image-181" title="hoptoad-fluid" src="http://blog.deolen.fr/wp-content/uploads/2009/06/hoptoad-fluid.png" alt="hoptoad-fluid" width="100" height="100" /></p>
<p><a href="http://www.symfony-project.org/">Symfony</a> fournit un mécanisme de journaux permettant de tracer toute sorte de messages, en leur affectant un niveau de criticité (info, warning, err, …). Ainsi, lorsque l’on constate un comportement anormal, on peut aller voir dans les logs les messages nous permettant de mieux comprendre le problème.</p>
<p>Néanmoins, on ne va pas fouiller ces journaux tous les jours, comment faire pour être automatiquement averti lorsqu’un problème survient ?</p>
<p>Il existe plusieurs plugins, par exemple <a href="http://www.symfony-project.org/plugins/sfErrorNotifierPlugin">sfErrorNotifierPlugin</a> ou  <a href="http://www.symfony-project.org/plugins/sfHoptoadNotifierPlugin">sfHoptoadNotifierPlugin</a>.</p>
<p><span id="more-180"></span></p>
<h3>sfErrorNotifierPlugin</h3>
<p><a href="http://www.symfony-project.org/plugins/sfErrorNotifierPlugin">sfErrorNotifierPlugin</a> est tout simple, il envoie un mail lorsqu’une exception est levée. Inconvénients :</p>
<ul>
<li> ne se base pas sur le journal, les messages de type ‘err’ par exemple ne seront donc pas nécessairement remontés.</li>
<li> se base sur la fonction mail(), ce qui peut parfois être restrictif.</li>
</ul>
<p>Ces 2 inconvénients sont cependant facilement contournables, faisant de sfErrorNotifierPlugin une excellente solution de secours.</p>
<h3>sfHoptoadNotifierPlugin</h3>
<p><a href="http://www.symfony-project.org/plugins/sfHoptoadNotifierPlugin">sfHoptoadNotifierPlugin</a> propose quelques mécanismes très pratiques.</p>
<p>Il s’agit d’un <em>plugin</em> qui, lors d’un problème, va se connecter au site <a href="http://www.hoptoadapp.com/">Hoptoad</a> (initialement dédié aux applications Rails) pour lui indiquer le problème.</p>
<p>Les 2 principaux inconvénients de ce <em>plugin</em> sont :</p>
<ul>
<li> comme sfErrorNotifierPlugin, ne se base pas sur le log (mais on va voir plus bas comment contourner ce problème)</li>
<li> nécessite une connexion internet (vers <a href="http://hoptoadapp.com/">http://hoptoadapp.com</a>)</li>
</ul>
<p><strong>Service Hoptoad</strong></p>
<p>Ce site offre deux services :</p>
<ul>
<li> Envoi de mail lors d’un problème</li>
<li> Tableau de bord de suivi des problèmes</li>
</ul>
<p>Ce qui est très intéressant est que le site détecte s’il s’agit d’erreurs similaires. Ainsi, si une centaine d’erreurs similaires sont déclarées, Hoptoad n’enverra qu’un seul mail.</p>
<p><img class="aligncenter size-full wp-image-183" title="hoptoad" src="http://blog.deolen.fr/wp-content/uploads/2009/06/hoptoad.png" alt="hoptoad" width="622" height="256" /></p>
<p>Ci-dessus, le tableau de bord indique qu’il y a eu 17 erreurs du type “Error while creating new event”.</p>
<p>Le tableau permet également de déclarer qu’un problème a été résolu (dans l’exemple ci-dessus, le 2eme message est grisé car déclaré comme résolu), et si une nouvelle erreur de cette famille survient, un nouveau mail est alors envoyé.</p>
<p><strong>Installation du plugin</strong></p>
<p>Je regrette que ce plugin ne soit ps disponible dans un dépôt Subversion : il utilise git. Toutefois, l’installation reste très simple (je ne fais que reprendre le readme.txt) :</p>
<pre><code>pear channel-discover pear.horde.org
pear install horde/yaml
pear install HTTP_Request
git clone git://github.com/krasio/sfhoptoadnotifierplugin.git \
             plugins/sfHoptoadNotifierPlugin</code></pre>
<p>Puis ajouter dans le app.yml de l&#8217;application souhaitée:</p>
<pre><code>all:
    sf_hoptoad_notifier_plugin:
      api_key: you_api_key_goes_here</code></pre>
<p>Et c&#8217;est tout !</p>
<p><strong>Ajustement du plugin pour se baser sur le journal</strong></p>
<p>Mon besoin est de détecter les messages de type [err], et, en début de vie de l’application, détecter les messages de type [warning]. Il suffit de détecter les évènements de type ’application.log’. Pour cela :</p>
<p>Dans le fichier sfHoptoadNotifierPluginConfiguration.class.php, ajouter à la fin de la méthode configure() le code suivant :</p>
<pre><code>$this-&amp;gt;dispatcher-&amp;gt;connect(
   'application.log',
   array('sfHoptoadNotifier', 'listenToApplicationLogEvent')
);</code></pre>
<p>Puis ajouter dans le fichier sfHoptoadNotifier.php la méthode:</p>
<pre><code>static public function listenToApplicationLogEvent(sfEvent $event) {

  $params = $event-&amp;gt;getParameters();
  // check if there is a log level
  if (isset($params['priority'])) {

    // level high enough ?
    $log_level_str = sfConfig::get('app_sf_hoptoad_notifier_plugin_log_level',
                                   'err');
    $log_level = constant('sfLogger::'.strtoupper($log_level_str));

    if ($params['priority'] &amp;lt;= $log_level) {
      // yes.
      $apiKey = sfConfig::get('app_sf_hoptoad_notifier_plugin_api_key', false);
      if ($apiKey) {
        if (!defined('HOPTOAD_API_KEY')) {
          define('HOPTOAD_API_KEY', $apiKey);
        }
        $priority_str = sfLogger::getPriorityName($params['priority']);
        $exception = new sfException("'[$priority_str] " . $params[0] . "'");
        Hoptoad::exceptionHandler($exception);
      }
    }
  }
}</code></pre>
<p>Enfin, ajouter dans le app.yml le niveau de criticité souhaité:</p>
<pre><code>  sf_hoptoad_notifier_plugin:
    api_key: you_api_key_goes_here
    log_level: warning # ou err</code></pre>
<p>Évidemment, plutôt que de modifier le plugin existant, j’aurais facilement pu faire un nouveau plugin puisque l’on se base sur un type d’évènement différent, mais je pense que le mieux est d’essayer d’enrichir le code de celui qui existe.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deolen.fr/2009/07/03/comment-etre-notifie-par-mail-lors-derreurs-symfony/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quelques exemples de services Twitter</title>
		<link>http://blog.deolen.fr/2009/06/15/quelques-exemples-de-services-twitter/</link>
		<comments>http://blog.deolen.fr/2009/06/15/quelques-exemples-de-services-twitter/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 19:53:49 +0000</pubDate>
		<dc:creator>Tristan</dc:creator>
				<category><![CDATA[Divers]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://blog.deolen.fr/?p=205</guid>
		<description><![CDATA[
Twitter permet entre autres de suivre l&#8217;activité de ses amis, de faire de la veille technologique, ou de s&#8217;entre-aider.
Néanmoins, la variété des services que Twitter peut rendre ne fait que s&#8217;accroître, voici quelques exemples.
Actualités
De nombreux media papiers diffusent les actualités, comme par exemple Le Monde, Le Figaro, ou Le Point.
Divers
Twit2do (en) &#8211; permet de gérer [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-209 alignleft" title="logo-twitter-54" src="http://blog.deolen.fr/wp-content/uploads/2009/06/logo-twitter-54.jpg" alt="logo-twitter-54" width="45" height="45" /></p>
<p><a href="http://twitter.com/">Twitter</a> permet entre autres de suivre l&#8217;activité de ses amis, de faire de la veille technologique, ou de s&#8217;entre-aider.</p>
<p>Néanmoins, la variété des services que Twitter peut rendre ne fait que s&#8217;accroître, voici quelques exemples.</p>
<p><span id="more-205"></span><strong>Actualités</strong></p>
<p>De nombreux media papiers diffusent les actualités, comme par exemple<a href="http://twitter.com/lemondefr"> Le Monde</a>,<a href="http://twitter.com/Le_Figaro"> Le Figaro</a>, ou<a href="http://twitter.com/LePoint"> Le Point</a>.</p>
<p><strong>Divers</strong></p>
<p><a href="http://www.twit2do.com/">Twit2do</a> (en) &#8211; permet de gérer des tâches et d&#8217;être notifié par twit.<a href="http://twittercal.com/"></a></p>
<p><a href="http://twittercal.com/">Twittercal</a> (en) &#8211; permet d&#8217;être notifié par twit des évènements planifiés sur Google Calendar.</p>
<p><a href="http://twitter.com/twittbourse">TwittBourse</a> (fr) &#8211; pour suivre le CAC40</p>
<p><a href="http://twitter.com/twanslate">Twansalte</a> &#8211; pour demander une traduction via twits, mais ne fonctionne plus. Sinon il y a <a href="http://twitrans.onehourtranslation.com/">Twitrans</a>.</p>
<p><a href="http://metweo.com/">Metweo</a> (fr) &#8211; diffuse la météo des grandes villes françaises.</p>
<p>Pour la recherche d&#8217;emploi, de nombreux comptes diffusent les offres: <a href="http://twitter.com/regionsjob">RegionsJob</a>, <a href="http://twitter.com/lesjeudis">Les Jeudis</a>, &#8230;</p>
<p><a href="http://twitpic.com/">TwitPic</a> (en) &#8211; permet de diffuser des photos via les twits</p>
<p><a href="http://search.twitter.com/">Twitter Search</a> (en), <a href="http://tweetscan.com/">Tweet Scan</a> (en) ou <a href="http://twitterfall.com/">TwitterFall</a> (en) &#8211; très utile pour rechercher de l&#8217;actu en temps réel, ou pour voir les sujets &laquo;&nbsp;chauds&nbsp;&raquo; du moment. <a href="http://tweetscan.com/">Tweet Scan</a> permet en plus d&#8217;être notifié automatiquement par mail sur les mots clés de notre choix.</p>
<p>Autrement, je suis tombé par hasard sur le service <a href="http://explore.twitter.com/">Explore</a>, si quelqu&#8217;un sait comment faire fonctionner &laquo;&nbsp;twitter blocks&nbsp;&raquo; &#8230;</p>
<p><strong>Offres commerciales</strong></p>
<p>Peut-etre que bientôt en France on pourra commander des pizzas, comme aux US avec <a href="http://twitter.com/nakedpizza">Naked Pizza</a> (en) ? En attendant, dans l&#8217;hexagone, <a href="http://twitter.com/dominos_pizzafr">Domino&#8217;s</a> (fr) diffuse ses offres spéciales et répond aux questions les consommateurs &#8230;</p>
<p>La plupart des agences de voyage proposent leurs offres via twitter. Par exemple <a href="http://twitter.com/lastminute_fr" target="_blank">LastMinute</a> ou <a href="http://twitter.com/sejour_voyage" target="_blank">Thomas Cook</a>.<a href="http://twitter.com/Pierre_vacances" target="_blank"><br />
</a></p>
<p><strong>Jeux</strong></p>
<p><a href="http://twitter.com/beatmytweet">beatmytweet</a> (en) -  diffuse des anagrammes, mais &#8230; en anglais !<a href="http://twitter.com/twitbrain/"></a></p>
<p><a href="http://twitter.com/twitbrain/">twitbrain</a> (en) &#8211; jeu de calcul mental. Très basique, l&#8217;intérêt est d&#8217;être hyper réactif.</p>
<p><a href="http://twitter.com/playtwivia">PlayTwivia</a> (en) &#8211; quizz</p>
<p><a href="http://jazzychad.net/rollthedice/">Roll.the.dice</a> (en) &#8211; permet de tirer au hasard des nombres, cartes, &#8230;</p>
<p><a href="http://chesstweets.com/">ChessTweets</a> (en) &#8211; pour jouer aux échecs !</p>
<p><strong>Annuaires</strong></p>
<p>Coté annuaires de services twitter, il y en a une palanquée, mais ils sont généralement vastes avec pas mal de déchets. Exemples: <a href="http://justtweetit.com">JustTweetIt</a> (en)<a href="http://www.twellow.com">, Twellow</a> (en)<a href="http://wefollow.com">, WeFollow</a> (en).</p>
<p>Ensuite, on trouve des listes nettement plus réduites mais de qualité sur divers blogs. J&#8217;ai trouvé un point d&#8217;entrée intéressant sur <a href="http://twitteradar.com/listes-twitter">TwitterRadar</a>.</p>
<p><strong>Au final &#8230;</strong></p>
<p>Honnêtement, même si la créativité des services n&#8217;a pas de limite, la plupart de ceux cités ci-dessus ont un intérêt assez limité, car il existe souvent des alternatives simples et plus &laquo;&nbsp;usuelles&nbsp;&raquo;.</p>
<p>Néanmoins, l&#8217;un des intérêts que je vois dans Twitter est le fait que l&#8217;on soit capable en permanence de twitter et de recevoir les twits via le mobile. Donc tout ce qui est actu, évènements, infos nécessaires &laquo;&nbsp;sur le champ&nbsp;&raquo; (tourisme, indications utiles, &#8230;) sont de loin pour moi les services les plus utiles (du moins pour l&#8217;instant !).</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 114px; width: 1px; height: 1px;">http://justtweetit.comJust</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.deolen.fr/2009/06/15/quelques-exemples-de-services-twitter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tutorial pour découvrir Facebook Connect</title>
		<link>http://blog.deolen.fr/2009/06/13/tutorial-pour-decouvrir-facebook/</link>
		<comments>http://blog.deolen.fr/2009/06/13/tutorial-pour-decouvrir-facebook/#comments</comments>
		<pubDate>Sat, 13 Jun 2009 13:12:07 +0000</pubDate>
		<dc:creator>Tristan</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[connect]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.deolen.fr/?p=138</guid>
		<description><![CDATA[Note: Cet article a été initialement diffusé sur le blog de Clever Age.
Annoncé il y a un peu moins d’un an et mis en application depuis six mois, Facebook propose son nouveau concept &#171;&#160;Facebook Connect&#160;&#187;. Les librairies et l’API sont relativement faciles à utiliser, mais le plus dur est de se repérer dans l’amas de [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note: Cet article a été initialement diffusé sur le <a href="http://www.clever-age.com/veille/blog/tutorial-pour-decouvrir-facebook-connect.html">blog de Clever Age</a></strong>.</p>
<p><img class="alignleft size-full wp-image-139" title="icon_facebook" src="http://blog.deolen.fr/wp-content/uploads/2009/05/icon_facebook.gif" alt="icon_facebook" width="50" height="50" />Annoncé il y a un peu moins d’un an et mis en application depuis six mois, Facebook propose son nouveau concept &laquo;&nbsp;Facebook Connect&nbsp;&raquo;. Les librairies et l’API sont relativement faciles à utiliser, mais le plus dur est de se repérer dans l’amas de documentation. Cet article a pour but d’expliquer le concept, de recoller les morceaux de documentation, et combler certains manques.</p>
<p><span id="more-138"></span></p>
<p>Une simple recherche sur Google de <a href="http://www.google.fr/search?q=facebook+api">facebook api</a> donne de nombreux points d’entrées a priori intéressants :</p>
<ul>
<li>Le<a href="http://developers.facebook.com/"> portail Facebook Developers</a></li>
<li><a href="http://developers.facebook.com/get_started.php?tab=tutorial">Introduction de l’API Facebook</a></li>
<li>Connexion à Facebook, alias <a href="http://developers.facebook.com/connect.php">Facebook Connect</a></li>
<li>Le <a href="http://wiki.developers.facebook.com/index.php/Main_Page">wiki</a></li>
<li>La <a href="http://wiki.developers.facebook.com/index.php/API">page wiki sur l’API</a></li>
<li>La <a href="http://wiki.developers.facebook.com/index.php/Facebook_Connect">page wiki sur Facebook Connect</a></li>
<li>etc&#8230;</li>
</ul>
<p>Toutes ces pages sont plus ou moins liées, et proposent des liens vers beaucoup d’autres pages contenant des informations plus ou moins redondantes.</p>
<p>On trouve de nombreux exemples html + javascript, mais peu d’exemples coté serveur (php, &#8230;), il est souvent nécessaire d’aller à la pêche dans les forums pour trouver des infos supplémentaires, ou le cas échéant, à faire de la rétro-ingénierie sur les bibliothèques fournies.</p>
<p>Bref, un beau petit merdier !</p>
<h3>Les bases de Facebook Connect</h3>
<p>Facebook propose deux types d’applications : celles qui sont intégrées sur le site de Facebook (&laquo;&nbsp;applications Facebook&nbsp;&raquo;), et les applications externes qui peuvent se connecter au site de Facebook pour récupérer et/ou envoyer des informations. C’est sur ce dernier type d’application que cet article se penche, c’est le concept <strong>Facebook Connect</strong> :</p>
<p><img class="aligncenter size-full wp-image-195" title="png_principe" src="http://blog.deolen.fr/wp-content/uploads/2009/06/png_principe1.png" alt="png_principe" width="658" height="510" /></p>
<p>Les intérêts sont multiples :</p>
<ul>
<li> Récupérer des informations sur l’internaute (profil, amis, photos, évènements, &#8230;). Cela permet par exemple à l’internaute de ne pas avoir à recréer son carnet d’adresses ou sa galerie photos. Cela permet également pour l’application de récupérer des contacts supplémentaires et cibler son marketing par exemple.</li>
<li> Exporter des données vers Facebook (photos, évènements, &#8230;). Par exemple, dans le cadre d’une application gérant des critiques de livres, il est possible de publier sur le flux de Facebook un message lors de chaque nouvelle critique. Cela augmente d’une part la visibilité de l’application tierce sur Facebook, et d’autre part la visibilité de l’internaute dans la communauté.</li>
<li> Amener facilement dans l’application externe la notion de communauté, grace à la fonction de &laquo;&nbsp;friend linking&nbsp;&raquo;.</li>
<li> Ne gérer qu’une seule authentification (celle de Facebook)</li>
<li> Associée à une application Facebook interne, l’application externe peut augmenter de manière importante sa visibilité.</li>
</ul>
<p>Pour développer un site se connectant à Facebook, le principe est le suivant :</p>
<ul>
<li> Déclarer l’application dans Facebook afin d’une part d’obtenir une clé d’API, et d’autre part afin d’indiquer à Facebook quelques règles sur le comportement (domaines acceptés, redirection suite à une déconnexion, etc&#8230;).</li>
<li> Mettre sur le serveur hébergeant l’application un fichier spécial, xd_receiver.htm, fourni par Facebook, permettant les échanges entre l’application et Facebook.</li>
<li> Développer l’application, en utilisant les balises Facebook (<a href="http://wiki.developers.facebook.com/index.php/XFBML">FBML</a>), les librairies javascript, et les autres librairies disponibles (PHP, &#8230;)</li>
</ul>
<h3>Déclarer notre application à Facebook</h3>
<p>Facebook fournit un tableau de bord pour gérer ses applications, qu’elles soient internes ou externes. Ce tableau de bord est accessible à l’url <a href="http://www.facebook.com/developers">http://www.facebook.com/developers</a> (il s’agit en fait d’une application Facebook, qu’il faut donc ajouter à son profil).</p>
<p>Même si l’on ne souhaite que créer une application externe, il faut néanmoins créer une application Facebook, qui sera &laquo;&nbsp;vide&nbsp;&raquo;. Cliquer sur &laquo;&nbsp;Créer une application&nbsp;&raquo; :</p>
<p><img class="aligncenter size-full wp-image-196" title="creation-app-general" src="http://blog.deolen.fr/wp-content/uploads/2009/06/creation-app-general.png" alt="creation-app-general" width="724" height="333" /></p>
<p>Les autres paramètres de l’onglet &laquo;&nbsp;Général&nbsp;&raquo; sont optionnels, et parlent d’eux-même.</p>
<p>Ensuite, aller sur l’onglet &laquo;&nbsp;Connexion&nbsp;&raquo;, qui est dédié précisément aux applications externes Facebook Connect :</p>
<p><img class="aligncenter size-full wp-image-197" title="creation-app-connect" src="http://blog.deolen.fr/wp-content/uploads/2009/06/creation-app-connect.png" alt="creation-app-connect" width="715" height="316" /></p>
<p>Les autres champs ne sont pas obligatoires.</p>
<p>La fonction &laquo;&nbsp;Friend Linking&nbsp;&raquo; n’est pas utilisée dans cet exemple, mais est décrite un peu plus bas.</p>
<p>La section &laquo;&nbsp;Template Bundles&nbsp;&raquo; n’est pas utilisée non plus dans cet exemple, elle permet de définir des templates pour <a href="http://wiki.developers.facebook.com/index.php/Feed.registerTemplateBundle">diffuser des informations</a> sur le profil Facebook de l’internaute.</p>
<h3>Fichier d&#8217;échange</h3>
<p>Il s’agit d’un simple fichier à créer, xd_receiver.htm,sur le serveur. Le contenu de ce fichier est défini sur le <a href="http://wiki.developers.facebook.com/index.php/Cross_Domain_Communication_Channel">wiki Facebook</a>. Il peut être aussi bien positionné à la racine que dans un sous-répertoire. Il s’agit d’un paramètre de configuration des bibliothèques que l’on verra plus tard.</p>
<h3>Developper l’application</h3>
<p><strong>Utilisation de la librairie JavaScript</strong></p>
<p>Structure typique d’une page utilisant la librairie JavaScript :</p>
<p><code> </code></p>
<pre>&lt;html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml"&gt;
&lt;head&gt; ... &lt;/head&gt;
&lt;body&gt;

 ...
 &lt;fb:login-button&gt;&lt;/fb:login-button&gt;
 ...

 &lt;script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"&gt;&lt;/script&gt;

 &lt;script type="text/javascript"&gt;
 FB.init(xxxxxxx, '/xd_receiver.htm');
 ...
 &lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Les points notables :</p>
<ul>
<li> Si l’on souhaite utiliser des balises Facebook (&lt;fb:xxx&gt;), il faut ajouter dans la balise &lt;html&gt; le namespace xmlns:fb=&nbsp;&raquo;http://www.facebook.com/2008/fbml&nbsp;&raquo;</li>
<li> Ajouter dans le  la librairie JS : &lt;script src=&nbsp;&raquo;http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php&nbsp;&raquo; type=&nbsp;&raquo;text/javascript&nbsp;&raquo;&gt;&lt;/script&gt;. Ne doit pas être placée dans le &lt;header&gt; car génère du code.</li>
<li> Les balises Facebook peuvent être ajoutées après la librairie, et avant le FB.init. C’est l’appel à FB.init() qui va (entre autres) déclencher le rendu de ces balises.</li>
<li> Avant de pouvoir appeler l’API, il faut d’abord initialiser l’application avec FB.init(api_key, channel_path). Le paramètre api_key est la clé d’API que l’on a obtenu lors de la création de l’application. Le channel_path est le chemin du fichier xd_receiver.htm, (en relatif ou en absolu).</li>
</ul>
<p>Le wiki est plutôt bien documenté sur l’utilisation de la librairie javascript, et regorge d’exemples, la suite de l’article se focalise donc plus sur l’utilisation de la partie PHP. Quelques exemples pour utiliser la librairie javascript :</p>
<ul>
<li> <a href="http://wiki.developers.facebook.com/index.php/Trying_Out_Facebook_Connect">Simple authentification</a></li>
<li> <a href="http://wiki.developers.facebook.com/index.php/Authenticating_Users_with_Facebook_Connect">Détection d’authentification, login, logout</a></li>
<li> <a href="http://wiki.developers.facebook.com/index.php/Facebook_Connect_Tutorial1">Affichage du profil suite à authentification</a></li>
<li> <a href="http://wiki.developers.facebook.com/index.php/JS_API_M_FB.Facebook.Init">Documentation de FB.init</a>, permettant également de détecter le statut authentifié ou non</li>
<li> &#8230;</li>
</ul>
<p><strong>Utilisation de la librairie PHP</strong></p>
<p>Cela devient un peu plus <em>freestyle</em>, car mal documenté.</p>
<p>Facebook propose une API RESTful dont la documentation succincte est disponible ici : <a href="http://wiki.developers.facebook.com/index.php/API">http://wiki.developers.facebook.com&#8230;</a>.</p>
<p>Pour bien comprendre son utilisation (URL, paramètres, enchainement des appels, &#8230;), pas d’autre solution que d’analyser le code d’une librairie cliente officielle telle que la librairie PHP. Et si on a la chance de développer un site dans un langage bénéficiant d’une telle librairie, autant l’utiliser directement !</p>
<p>Donc commencer par télécharger la <a href="http://svn.facebook.com/svnroot/platform/clients/packages/facebook-platform.tar.gz">librairie PHP</a>, et la dézipper. Les librairies utiles sont dans le répertoire facebook-platform/php. Il y a deux fichiers interessants :</p>
<ul>
<li> facebook.php : contient la classe principale Facebook. Il s’agit du point d’entrée, cette classe se charge d’initialiser la connexion, et d’instancier un client REST (cf. ci-dessous).</li>
<li> facebookapi_php5_restlib.php : contient la classe FacebookRestClient fournissant toutes les méthodes nécessaires pour aller appeler l’API REST de Facebook. Par exemple, l’API propose une fonction &laquo;&nbsp;facebook.friends.get&nbsp;&raquo; pour obtenir la liste des amis d’une personne. La classe FacebookRestClient fournit une méthode friends_get() qui appelle l’API en formatant correctement les paramètres, et qui désérialise/analyse la réponse pour fournir les valeurs de retour.</li>
</ul>
<p>Exemple d’utilisation :</p>
<p><code> </code></p>
<pre>&lt;?php
// Librairie PHP officielle
require_once('facebook-platform/php/facebook.php');

// Initialisation
// Le SECRET_CODE est obtenu lors de la création de l'application
$facebook = new Facebook(API_KEY, SECRET_CODE);

// si l'internaute est authentifié, retourne son identifiant
// sinon, redirige vers une page d'authentification facebook, puis retourne sur cette page
$user_id = $facebook-&gt;require_login();

// pour recuperer a tout moment l'identifiant de l'internaute:
// $user_id = $facebook-&gt;user;

// pour appeler l'API Facebook:
// $facebook-&gt;api_client-&gt;... (se référer au code source facebookapi_php5_restlib.php)</pre>
<p>L’exemple ci-dessus détecte si l’internaute est authentifié, et le cas échéant, le redirige vers Facebook pour s’authentifier. Néanmoins, on souhaite fréquemment détecter si l’internaute est authentifié, sans pour autant le rediriger de force vers Facebook le cas échéant. Pour cela, il suffit simplement de tester la valeur $facebook-&gt;user:</p>
<p><code> </code></p>
<pre>&lt;?php
// Librairie PHP officielle
require_once('facebook-platform/php/facebook.php');

// Initialisation
$facebook = new Facebook("api_key", "secret_code");

// Authentifié ?
if ($facebook-&gt;user == NULL) {
 // non authentifié
} else {
 // authentifié
}</pre>
<p>Exemple de code affichant la liste des  amis :</p>
<p><code> </code></p>
<pre>&lt;?php
// Librairie PHP officielle
require_once('facebook-platform/php/facebook.php');

// Initialisation
$facebook = new Facebook("api_key", "secret_code");

// si l'internaute est authentifié, retourne son identifiant
// sinon, redirige vers une page d'authentification facebook, puis retourne sur cette page
$user_id = $facebook-&gt;require_login();

// recupere les identifiants des amis
$friends_uid = $facebook-&gt;api_client-&gt;friends_get();

// recupere les infos utiles des amis
$friends_data = $facebook-&gt;api_client-&gt;users_getInfo($friends_uid, array('uid', 'first_name', 'last_name'));

var_dump($friends_data);</pre>
<p>Note 1 : dans certains cas, l’appel à $facebook-&gt;api_client-&gt;friends_get() (ou l’appel à d’autres méthodes) peut provoquer une erreur. C’est un effet de bord qui peut arriver lorsque l’internaute n’est pas &laquo;&nbsp;tout à fait&nbsp;&raquo; déconnecté, lorsque ses <em>cookies</em> ne sont nettoyés qu’à moitié. Il est donc recommandé de fiabiliser les appels à ces méthodes en ajoutant un try/catch.</p>
<p>Note 2 : la liste des informations que l’on peut obtenir sur les utilisateurs est décrite <a href="http://wiki.developers.facebook.com/index.php/Users.getInfo">ici</a>. Une restriction importante : <strong>il n’est pas possible d’obtenir l’adresse email</strong> ! Le seul contournement qu’offre l’API Facebook est un mécanisme pour envoyer des emails aux utilisateurs souhaités.</p>
<p>Note 3 : la fonction $facebook-&gt;require_login redirige l’utilisateur vers Facebook, le risque est donc de ’perdre’ l’internaute. Pour l’authentification, je préfère utiliser la version JavaScript (&lt;fb:login-button&gt;) qui ne fait qu’ajouter une fenetre popup pour s’authentifier.</p>
<p>Liens utiles :</p>
<ul>
<li> <a href="http://wiki.developers.facebook.com/index.php/API">API REST Facebook</a></li>
<li> <a href="http://wiki.developers.facebook.com/index.php/PHP">Page d’accueil</a> de la bibliothèque PHP officielle couvrant de manière partielle l’API</li>
<li> <a href="http://pear.php.net/package/Services_Facebook">Librairie PHP non-officielle</a> (PEAR) couvrant toute l’API</li>
</ul>
<p><strong>Alléger le serveur en mixant PHP, JavaScript et FBML</strong></p>
<p>Tout développement côté serveur peut engendrer une charge importante, parfois le serveur a peu d’intérêt à connaître certaines informations. D’où l’intérêt d’utiliser les balises Facebook (FBML) et les librairies javascript. Et inversement, trop utiliser les librairies JS plombent les performances côté internaute, et nuisent à l’accessibilité. Tout l’art est donc de trouver le juste milieu.</p>
<p>Par exemple, pour afficher la liste des amis et leur photo, le serveur peut se charger de récupérer les identifiants, et le navigateur de l’internaute se charger de récupérer les photos :</p>
<p><code> </code></p>
<pre>&lt;html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml"&gt;
&lt;head&gt;&lt;/head&gt;
&lt;body&gt;
&lt;?php

// Librairie PHP officielle
require_once('facebook-platform/php/facebook.php');

// Initialisation
$facebook = new Facebook("api_key", "secret_code");

// recupere les identifiants des amis
$user_id = $facebook-&gt;require_login();
$friends_uid = $facebook-&gt;api_client-&gt;friends_get();
?&gt;

&lt;!-- affiche les photos des amis --&gt;
&lt;?php foreach($friends_uid as $uid) : ?&gt;
 &lt;fb:profile-pic uid="&lt;?php echo $uid; ?&gt;" linked="true"&gt;&lt;/fb:profile-pic&gt;
&lt;?php endforeach; ?&gt;

&lt;!-- necessaire pour le rendu FBML --&gt;
&lt;script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
 FB.init("api_key", 'xd_receiver.htm');
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Note 1 : dans le cas d’une application Facebook Connect, il faut utiliser la forme &laquo;&nbsp;&lt;fb:xxx&gt;&lt;/fb:xxx&gt;&nbsp;&raquo; à la place de &laquo;&nbsp;&lt;fb:xxx /&gt;&nbsp;&raquo;.</p>
<p>Liens utiles :</p>
<ul>
<li> <a href="http://wiki.developers.facebook.com/index.php/FBML">Balises Facebook</a> (Facebook Markup Language, alias FBML)</li>
<li> <a href="http://wiki.developers.facebook.com/index.php/JS_API_Index">Librairie cliente JavaScript</a></li>
</ul>
<h3>Quelques notions supplémentaires</h3>
<p><strong>Développement local</strong></p>
<p>En phase de développement, il est nettement plus productif de développer en local sur son poste, puis ensuite, une fois l’application validée, d’exporter le code source vers le serveur définitif. Il est tout à fait possible de développer des applications Facebook Connect en local, en suivant ces consignes :</p>
<p>L’URL que l’on a fourni lors de la création de l’application Facebook doit exister, et doit être accessible par Facebook (même s’il n’y a rien).</p>
<p>Le fichier xd_receiver.htm doit être sur le serveur définitif, car Facebook essaiera de le charger.</p>
<p>L’URL utilisée pour le développement local doit être sur le même domaine que celui déclaré lors de la création de l’application. En clair : si le domaine déclaré est ’site.fr’, alors ajouter dans le fichier <em>hosts</em> local l’entrée : 127.0.0.1 local.site.fr</p>
<p>Et créer dans le serveur web un hôte virtuel basé sur le nom de domaine local.site.fr.</p>
<p><strong>Friend linking</strong></p>
<p>Comme on l’a vu dans l’exemple un peu plus haut, il est facile d’obtenir la liste des amis d’un internautes. Cependant, comment savoir si parmi cette liste, certains ont un compte sur notre application ? On peut éventuellement se baser sur le prénom et le nom, mais ce n’est pas une méthode sûre en raison des risques d’homonymie et de la manière dont les utilisateurs ont saisi leur profil (par exemple ’Frederic’ sur le profil Facebook, et ’Fred’ sur notre application).</p>
<p>La fonction &laquo;&nbsp;friend linking&nbsp;&raquo; (activée lors de la création de l’application) permet précisément de faire ce lien, afin de recréer les communautés au sein de notre application.</p>
<p><strong>Librairies clientes</strong></p>
<p><a href="http://wiki.developers.facebook.com/index.php/Client_Libraries">Liste des librairies clientes</a> (PHP, ActionScript, &#8230;)</p>
<p><strong>Facebook Query Language</strong></p>
<p>Facebook propose un language de requêtage pour rechercher des utilisateurs, photos, évènements, &#8230; Il s’agit  du <a href="http://wiki.developers.facebook.com/index.php/FQL">Facebook Query Language</a> (FQL).</p>
<p>Ces requêtes peuvent être par exemple appelées via JavaScript avec FB.ApiClient.Fql_query($query) ou PHP avec la fonction $facebook-&gt;api_client-&gt;fql_query($query).</p>
<p><strong>Exemples de sites utilisant Facebook Connect</strong></p>
<p>Ce n’est que depuis très peu de temps que l’on commence à trouver des sites de grande audience exploitant Facebook Connect. On peut par exemple citer :</p>
<ul>
<li> <a href="http://www.lequipe.fr/">L’Equipe</a> qui a mis son nouveau site en ligne le 19 mai et proposant une barre Facebook pour chatter avec les autres internautes.</li>
<li> <a href="http://www.digg.com/">Digg</a> qui publie dans le fil des actualités Facebook les nouvelles pages bookmarquées par l’internaute</li>
<li> <a href="http://www.joost.com/">Joost</a>, <a href="http://www.vimeo.com/">Vimeo</a>, et <a href="http://www.cbs.com/">CBS</a> utilisent Facebook Connect pour le partage des vidéos.</li>
</ul>
<p>Et un peu de promo pour un site perso mettant en oeuvre Facebook Connect: <a href="http://www.pocme.net">PocMe </a>permettant d&#8217;être automatiquement notifié par mail des anniversaires des amis enregistrés suk.r Facebook.</p>
<p><code> </code></p>
<h3>En savoir plus:</h3>
<ul>
<li> <a href="http://wiki.developers.facebook.com/index.php/Facebook_Connect">Page d’accueil Facebook Connect</a></li>
<li> <a href="http://developers.facebook.com/news.php?blog=1&amp;story=213">Utilisation de Facebook Connect sur iPhone</a></li>
<li> Règles d’utilisation de <a href="http://wiki.developers.facebook.com/index.php/Platform_Policy">Facebook</a> et <a href="http://wiki.developers.facebook.com/index.php/Additional_Policies_Governing_Facebook_Connect">Facebook Connect</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.deolen.fr/2009/06/13/tutorial-pour-decouvrir-facebook/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PocMe, coté technique: Symfony</title>
		<link>http://blog.deolen.fr/2009/04/29/pocme-cote-technique-symfony/</link>
		<comments>http://blog.deolen.fr/2009/04/29/pocme-cote-technique-symfony/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 17:00:35 +0000</pubDate>
		<dc:creator>Tristan</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://blog.deolen.fr/?p=66</guid>
		<description><![CDATA[Le but de PocMe est surtout pour moi de tester certaines solutions techniques.
Donc principalement Symfony 1.2 et Doctrine.

Symfony 1.2
 PocMe est développé en PHP, basé sur le framework Symfony (branche 1.2). Du bonheur en barre   Il permet de se concentrer sur l&#8217;essentiel, à savoir la partie métier. Toute la partie technique usuelle est [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-115" title="logo-4" src="http://blog.deolen.fr/wp-content/uploads/2009/01/logo-4.png" alt="logo-4" width="172" height="73" />Le but de <a href="http://www.pocme.net">PocMe</a> est surtout pour moi de tester certaines solutions techniques.</p>
<p>Donc principalement <a href="http://www.symfony-project.org/">Symfony 1.2</a> et <a href="http://www.doctrine-project.org/">Doctrine</a>.</p>
<p><span id="more-66"></span></p>
<h3>Symfony 1.2</h3>
<p><a href="http://www.pocme.net"> PocMe</a> est développé en PHP, basé sur le framework <a href="http://www.symfony-project.org">Symfony</a> (branche 1.2). Du bonheur en barre <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Il permet de se concentrer sur l&#8217;essentiel, à savoir la partie métier. Toute la partie technique usuelle est laissée au framework.</p>
<p>La principale difficulté est que l&#8217;on a régulièrement tendance à implémenter quelquechose, sans savoir que symfony fournit déjà des outils pour cela. Donc pour être efficace avec symfony, il y a un ticket d&#8217;entrée minimum pour bien comprendre les notions de controleurs, de filtres, de slots, d&#8217;helpers, etc&#8230;</p>
<p>Donc passage par la case doc obligatoire, et là, c&#8217;est un régal: <a href="http://www.symfony-project.org/book/1_2/">l&#8217;aide en ligne</a> ainsi que le <a href="http://www.symfony-project.org/jobeet/1_2/Doctrine/en/">tutorial jobeet</a> constituent l&#8217;une des principales forces de symfony, tant par la pédagogie que par l&#8217;ensemble des sujets couverts.</p>
<p>Seul petit bémol sur la <a href="http://www.symfony-project.org/api/1_2/">doc de l&#8217;API</a>, qui n&#8217;est pas propre à symfony d&#8217;ailleurs: j&#8217;aurais aimé que l&#8217;index des méthodes soit classé par ordre alphabétique, et que le résumé soit affiché à droite du nom de la méthode. Car en l&#8217;état, cet index est quasi inutilisable, je passais mon temps à faire des control-F. A moins d&#8217;utiliser la doc en ligne via un IDE.</p>
<p>Une autre source d&#8217;info extrêmement intéressante, c&#8217;est le <a href="http://prendreuncafe.com/blog/post/2008/03/24/Le-code-de-Symfonians-en-open-source">code source</a> de <a href="http://symfonians.net/">Symfonians</a>, qui permet de découvrir des fonctionnalités dont on n&#8217;avait pas idée, des idées de solutions techniques et conception (je pense par exemple à la gestion des mails et de leurs templates, de l&#8217;implémentation de sfGuard, &#8230;), bref, j&#8217;ai énormément pompé sur ce site, merci <a href="http://prendreuncafe.com/">NiKo</a> <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>D&#8217;ailleurs, au sujet de sfGuard, il s&#8217;agit d&#8217;un plugins, certes, mais il ne faut pas s&#8217;imaginer qu&#8217;il suffit de l&#8217;activer pour avoir toute la gestion des utilisateurs. Tout ce qui concerne l&#8217;enregistrement, la confirmation, l&#8217;envoi de mot de passe, la gestion du profil, &#8230; reste à implémenter. Ce qui demande un effort considérable. Bien qu&#8217;une fois fait, j&#8217;imagine qu&#8217;il est facile de récupérer la majorité du code pour l&#8217;appliquer à une nouvelle appli.</p>
<h3>Forms</h3>
<p>Bien qu&#8217;il s&#8217;agisse d&#8217;un composant intégré à Symfony, il s&#8217;agit d&#8217;un package important, qui a fait couler pas mal d&#8217;encre.</p>
<p>Pour créer un formulaire, il faut avoir son bac ! Au début, on copie/colle un exemple de formulaire pour faire le notre, ou on le génère automatiquement, mais si on veut pousser le bouchon un peu plus loin, il faut retrousser ses manches et bien lire la doc (<a href="http://www.symfony-project.org/forms/1_2/en/">plusieurs chapitres dédiés</a>). Le point positif est que la partie complexe réside dans l&#8217;objet formulaire et ses éventuels validateurs/formatteurs, et une fois cela fait, le code dans les actions et les templates reste simple.</p>
<p>Ma principale crainte en épluchant la documentation était de voir symfony tomber dans certains écueils de certains frameworks Java. Instruction trouvée sur le site du framework Hibernate:</p>
<blockquote><p><strong>Avoid over-design</strong>: aiming for too much abstraction and flexibility at an early stage is a great way to waste time that could be better spent solving actual problems that your actual users are facing. Do the simplest thing that can possibly work. Don&#8217;t try to solve problems that your users don&#8217;t care about. And it DOES NOT matter if your implementation is inelegant, at least initially. What matters is delivering useful functionality in a timely manner</p></blockquote>
<p>Une fois les principes intégrés, un peu suspicieux, et après avoir un peu galéré pour les 2/3 premiers formulaires, je reconnais que le développement des suivants est de plus en plus rapide, et plutôt agréable.</p>
<p>Donc lorsqu&#8217;il s&#8217;agit de formulaires plutôt standard, la productivité est bonne. Lorsque les besoins deviennent plus spécifiques, la nouvelle mouture des formulaires n&#8217;est pas vraiment optimisée pour du développement bas niveau.</p>
<p>Exemple: j&#8217;ai pas mal sué avec la notion d&#8217;erreur globale &#8230; J&#8217;avais besoin d&#8217;avoir des templates un peu travaillés en fonction du type de l&#8217;erreur globale. Je n&#8217;ai pas réussi. Peut-etre y&#8217;a-t-il un bug, ou plus probablement, j&#8217;ai raté une ligne dans la doc. Toujours est-il que ce n&#8217;est pas évident.</p>
<p>Mais bon, ma petite appli n&#8217;a que des formulaires plutôt basiques, donc dans l&#8217;ensemble, j&#8217;ai plutôt apprécié le mécanisme.</p>
<h3>Doctrine</h3>
<p>Pour varier un peu les plaisirs, vu que je connaissais déjà <a href="http://propel.phpdb.org/trac/">Propel</a>, cette fois-ci je suis parti sur <a href="http://www.doctrine-project.org/">Doctrine</a>. Quelques points:</p>
<ul>
<li>La documentation est dense, et on ne trouve pas toujours l&#8217;information souhaitée dans le chapitre auquel on s&#8217;attend. Et certaines informations importantes sont noyées dans le reste de l&#8217;info (j&#8217;ai mis du temps à découvrir les magic finder !). Néanmoins, la doc a pas mal évolué entre temps. Et je viens à l&#8217;instant de découvrir un <a href="http://www.symfony-project.org/doctrine/1_2/en/">tutorial de Doctrine</a> sur le site de symfony, voilà ce qui me manquait <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<ul>
<li>Les possibilités de schéma sont nettement plus puissantes sous <a href="http://www.doctrine-project.org/documentation/manual/1_1/en/introduction">Doctrine 1.1</a> que sous <a href="http://propel.phpdb.org/trac/wiki/Users/Documentation/1.2/UserGuide">Propel 1.2</a>.</li>
</ul>
<ul>
<li>La contrepartie est que du coup, le schema.yml est plus complexe, il faut toujours sa cheat sheet à coté de soi (alors que pour Propel c&#8217;etait particulièrement simple).</li>
</ul>
<ul>
<li>Le requêtage est très proche du SQL. Avec Propel, on en était très loin, et dès que l&#8217;on voulait faire des requêtes complexes (alliant plusieurs jointures, clauses et/ou, &#8230;), il vallait mieux passer en mode requête SQL (sinon le code devenait difficilement maintenable).</li>
</ul>
<ul>
<li>Performances ? Aucune idée <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>En tout cas, parfaitement intégré à Symfony.</p>
<h3>Fonctions PocMe</h3>
<p>Concernant l&#8217;appli <a href="http://www.pocme.net">PocMe</a>, qq points notables:</p>
<p><strong>S&#8217;enregistrer</strong>: sur tous les sites que je connais, pour s&#8217;enregistrer, il faut saisir 2 fois le mot de passe. Et je trouve ça irritant ! Ca devient tellement une habitude qu&#8217;au final, je fais un copier/coller du 1er password dans le 2nd, ce qui enlève tout interet à la vérification, je sais <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Je me doute bien que le but est d&#8217;avertir l&#8217;internaute s&#8217;il a fait une faute de frappe. Et alors ? S&#8217;il s&#8217;est trompé, il suffit qu&#8217;il fasse la demande &#8216;mot de passe perdu&#8217;, et voilà ! Honnêtement, dans combien de cas on se plante dans la saisie d&#8217;un mot de passe ? Disons qu&#8217;on est vraiment manchot, on se trompe une fois sur 5. Et du coup, pour 4 inscriptions sur 5, ce champs supplémentaire n&#8217;a aucun intérêt si ce n&#8217;est alourdir le formulaire d&#8217;inscription. Bref, j&#8217;avais envie de changer un peu cette habitude (oui, je sais, je suis un énorme rebelle <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> )</p>
<p><strong>Dates</strong>: c&#8217;est l&#8217;aspect le plus complexe de l&#8217;application. Car gérer des dates fixes, pas de pb, mais gérer des dates répétées (tous les mois par ex), c&#8217;est une horreur. Donc le gros du temps passé sur l&#8217;appli concerne la gestion de ces date.</p>
<p><strong>Mails</strong>: j&#8217;ai tout simplement repris le principe que j&#8217;ai vu dans Symfonians, à savoir sfSwiftPlugin, allié à un module dédié pour les templates, et se connectant à un serveur SMTP de Google Apps. Seul petit hic: les performances pour l&#8217;envoi de mails, pas très rapide, il faudra que je voie si je peux améliorer cela.</p>
<p><strong>Tests automatiques</strong>: comme tout le monde, j&#8217;adore ce principe, j&#8217;avais commencé à les mettre en place au début en utilisant la lib de symfony, mais ça prend du temps à mettre en place, j&#8217;ai fini par abandonner <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p><strong>Scripts automatiques</strong>: lancés via cron évidemment, j&#8217;ai un peu galéré car j&#8217;ai réalisé tardivement que mon script devait appeler le controlleur (notamment à cause des templates de mails). Je ne souhaitais pas passer par Apache (à cause des éventuels timeout). Je suis donc passé par le sfConsoleController au lieu de l&#8217;habituel sfWebController. Puis j&#8217;ai dû bidouiller un poil pour qu&#8217;il soit exécuté avec le rôle admin.</p>
<p>Voilà, au final, je me suis plutôt bien amusé, et ce n&#8217;est pas fini <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deolen.fr/2009/04/29/pocme-cote-technique-symfony/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>PocMe, service de notification par mail</title>
		<link>http://blog.deolen.fr/2009/04/19/pocme-service-de-notification-par-mail/</link>
		<comments>http://blog.deolen.fr/2009/04/19/pocme-service-de-notification-par-mail/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 21:30:06 +0000</pubDate>
		<dc:creator>Tristan</dc:creator>
				<category><![CDATA[Divers]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[notification]]></category>
		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://blog.deolen.fr/?p=56</guid>
		<description><![CDATA[Un peu d&#8217;auto-promo pour une petite application que je viens de mettre en ligne: PocMe, un service gratuit de notification par mail.
Le principe est d&#8217;avoir un service très simple d&#8217;utilisation, qui ne fait que vous envoyer un petit mail le jour J, rien de plus, il ne vous proposera pas un formulaire d&#8217;inscription de 10 [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-115" title="logo-4" src="http://blog.deolen.fr/wp-content/uploads/2009/01/logo-4.png" alt="logo-4" width="172" height="73" />Un peu d&#8217;auto-promo pour une petite application que je viens de mettre en ligne: <a href="http://www.pocme.net" target="_self">PocMe, un service gratuit de notification par mail</a>.</p>
<p>Le principe est d&#8217;avoir un service très simple d&#8217;utilisation, qui ne fait que vous envoyer un petit mail le jour J, rien de plus, il ne vous proposera pas un formulaire d&#8217;inscription de 10 pages et ne vous fera pas le café.</p>
<p>Ceci pour vous éviter d&#8217;oublier un anniversaire ou toute autre tâche importante (loyer, réservation, &#8230;).</p>
<p><span id="more-56"></span></p>
<p>Fonctionnellement, le principe est simple: après vous être enregistré, vous pouvez sélectionner une date, un message, et une fréquence (tous les ans, tous les mois, une seule fois). C&#8217;est tout.</p>
<p>Bien sûr, vous pouvez ajouter autant de dates que vous le souhaitez, ou supprimer un évènement erroné.</p>
<p>Pour l&#8217;instant, l&#8217;application est dans une version assez basique, mais parmi les évolutions prévues: traduction dans d&#8217;autres langues, amélioration de l&#8217;ergonomie et du design, et quelques autres idées (import des anniversaires  des copains dans Facebook, widget rappellant les prochaines échéances, notification par twit, &#8230; la liste des idées est longue, mais après faut les développer !).</p>
<p>Coté technique, j&#8217;y reviendrai plus tard, sachez juste pour l&#8217;instant que c&#8217;est basé sur <a title="symfony" href="http://www.symfony-project.org">Symfony 1.2</a> et hébergé chez <a title="Pastis-Hosting" href="http://pastis-hosting.net">Pastis-Hosting</a> (l&#8217;hébergeur pas plus haut que le bord).</p>
<p>Et n&#8217;hésitez pas à me remonter tout bug rencontré <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deolen.fr/2009/04/19/pocme-service-de-notification-par-mail/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Profiler PHP</title>
		<link>http://blog.deolen.fr/2009/02/28/profiler-php/</link>
		<comments>http://blog.deolen.fr/2009/02/28/profiler-php/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 21:27:10 +0000</pubDate>
		<dc:creator>Tristan</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[mémoire]]></category>
		<category><![CDATA[performances]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[profiler]]></category>
		<category><![CDATA[xdebug]]></category>

		<guid isPermaLink="false">http://blog.deolen.fr/?p=93</guid>
		<description><![CDATA[Le but de ce billet est simplement de montrer qu&#8217;il est facile de mettre en place un profiler et que l&#8217;intérêt peut être énorme.
Pour rappel, un profiler est un outil dont le but est d&#8217;optimiser une application. Que ce soit pour la faire exécuter plus rapidement ou pour diminuer la mémoire consommée. Habitué au profiling [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-110" title="jauge-thumb4561403" src="http://blog.deolen.fr/wp-content/uploads/2009/02/jauge-thumb4561403.jpg" alt="jauge-thumb4561403" width="108" height="108" />Le but de ce billet est simplement de montrer qu&#8217;il est facile de mettre en place un profiler et que l&#8217;intérêt peut être énorme.</p>
<p>Pour rappel, un profiler est un outil dont le but est d&#8217;optimiser une application. Que ce soit pour la faire exécuter plus rapidement ou pour diminuer la mémoire consommée. Habitué au profiling java (via OptimizeIt, JProbe, JProfiler &#8230;), ce n&#8217;est que récemment que je me suis intéressé au profiling PHP (j&#8217;entends déjà les mauvaises langues siffler &laquo;&nbsp;ben oui, php, c&#8217;est rapide et léger, pas besoin de profiler !&nbsp;&raquo;).</p>
<p><span id="more-93"></span></p>
<h3>Profiling CPU</h3>
<p>La rapidité est un facteur intéressant aussi bien pour un script exécuté par Apache que pour un script exécuté en ligne de commande.</p>
<p>Avant d&#8217;expliquer comment installer le profiler, d&#8217;abord un simple exemple d&#8217;utilisation. Sur un CMS (Drupal), nous avons remarqué que de simples requêtes HTTP faisait grimper le CPU d&#8217;Apache à 100% pendant quelques secondes. Une simple coup de profiling permet de trouver très rapidement le coupable:</p>
<p><img class="aligncenter size-full wp-image-106" title="profiler-speed" src="http://blog.deolen.fr/wp-content/uploads/2009/02/prof-speed-a.png" alt="profiler-speed" width="729" height="224" /></p>
<p>L&#8217;outil ci-dessus montre que la requête HTTP (index.php) a duré 2.8 secondes, et sur ces 2.8 secondes, la fonction &#8216;theme&#8217; a pris 2.4 secondes. Après, il suffit de suivre le fil en double-cliquant sur les lignes jusqu&#8217;à trouver une fonction suspecte:</p>
<p><img class="aligncenter size-full wp-image-107" title="prof-speed-b" src="http://blog.deolen.fr/wp-content/uploads/2009/02/prof-speed-b.png" alt="prof-speed-b" width="729" height="193" /></p>
<p>Et là on trouve le coupable: la fonction JSMin:minify, qui a elle seule, prend 2.2 secondes. Cette fonction sert à minifier à la volée les scripts JS que nous avons mis en place dans Drupal. Dans ce cas concret, l&#8217;optimisation est simple: nous minifions nous-meme les scripts, et la requête HTTP passe de 2.8 secondes à 0.6 seconde !</p>
<p>Remarque: en mesurant le temps d&#8217;exécution de la fonction, on mesure également le temps d&#8217;exécution des requêtes SQL, ce qui permet éventuellement de trouver des requêtes à optimiser.</p>
<p>Cet exemple permet de montrer qu&#8217;il est très facile de trouver le problème. Après, ce n&#8217;est pas pour autant que l&#8217;on trouve la solution, mais c&#8217;est déjà très intéressant dans bon nombre de cas.</p>
<p>Installation de l&#8217;outil:</p>
<p>L&#8217;extension php xdebug permet de tracer les performances de chaque instruction exécutée. Pour l&#8217;installer, c&#8217;est très simple:</p>
<ul>
<li>Sur Ubuntu: cf. <a href="http://prendreuncafe.com/blog/post/2006/11/29/Installer-XDebug-sur-Ubuntu-et-lutiliser-avec-Symfony">procédure d&#8217;installation XDebug sur Ubuntu</a></li>
<li>Sur Windows:  télécharger sur le <a href="http://www.xdebug.org/download.php">site de XDebug</a> la DLL correspondant à notre version de php et la sauvegarder n&#8217;importe où.</li>
</ul>
<p>Ensuite, il faut configurer XDebug. Cela se fait simplement en éditant le fichier php.ini:</p>
<pre><code>zend_extension=/path/to/xdebug.so_or_dll
xdebug.profiler_enable = On
xdebug.profiler_output_dir = /whatever/folder
xdebug.profiler_output_name = "cachegrind.out.%u"</code></pre>
<p>Maintenant, tout appel à php engendrera des fichiers de logs dans le répertoire défini ci-dessus. Attention, ces fichiers peuvent être très volumineux !</p>
<p>Pour les dépouiller, il faut utiliser <a href="http://kcachegrind.sourceforge.net/html/Home.html">KCachegrind </a>(KDE) ou <a href="http://sourceforge.net/project/showfiles.php?group_id=135562">WinCacheGrind </a>(Windows). Ce dernier est basique mais fournit l&#8217;essentiel (les snapshots ci-dessus ont été pris avec WinCacheGrind). KCacheGrind est plus complet, le site de XDebug explique les <a href="http://www.xdebug.org/docs/profiler">bases de son utilisation</a>. Il est intéressant de remarquer que l&#8217;on peut très bien avoir des logs créés par un serveur Debian et ensuite analysés sur un poste Windows.</p>
<h3>Profiling mémoire</h3>
<p>On a rarement recours au profiling mémoire pour des scripts exécutés sur un serveur HTTP. La durée de la requête étant en général au plus de quelques secondes, la mémoire n&#8217;a pas le temps d&#8217;atteindre des sommets, et si c&#8217;est le cas, on a vite tendance à augmenter le paramètre memory_limit dans le php.ini sans trop se poser de questions !!!</p>
<p>Par contre, pour des scripts exécutés en ligne de commande, qui peuvent durer plusieurs minutes, cela peut devenir problématique. Notre besoin était d&#8217;importer des contenus externes (dans Drupal). Notre script bouclait donc sur les 4.000 contenus à importer. Or, à chaque nouvelle itération, la mémoire augmentait de 100ko. Il y avait donc une fuite mémoire qu&#8217;il était nécessaire de colmater.</p>
<p>Malheureusement, je n&#8217;ai pas trouvé d&#8217;outil adéquat pour du profiling mémoire. Les outils java cités plus haut permettaient de manière très efficace de repérer quels étaient les données qui étaient encore en mémoire à tort, et par qui elles avaient été allouées. Mais je n&#8217;ai pas trouvé l&#8217;équivalent en php.</p>
<p>XDebug fournit des informations mémoires en le configurant ainsi:</p>
<pre><code>xdebug.show_mem_delta = On
xdebug.trace_output_dir = /whatever/folder
xdebug.trace_output_name="trace.%u"</code></pre>
<p>Mais je n&#8217;ai pas trouvé d&#8217;outil capable de dépouiller les fichiers de log (les analyser manuellement n&#8217;est vraiment pas productif), et j&#8217;ai l&#8217;impression que ces fichiers ne contiennent pas toutes les informations utiles (notamment la liste des objets encore alloués, par qui).</p>
<p>Donc sur ce coup là, je m&#8217;en suis tiré avec du profiling cpu, en prenant pour hypothèse que la fonction qui prend le plus de CPU serait la fonction qui prend le plus de mémoire ! Et par une immense chance, cela a fonctionné (le vilain petit canard était le module pathauto de Drupal) !</p>
<p>Mais si vous connaissez des outils, je suis preneur !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deolen.fr/2009/02/28/profiler-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Je suis l&#8217;ami des pigeons &#8230; rotis !</title>
		<link>http://blog.deolen.fr/2009/02/01/je-suis-lami-des-pigeons-rotis/</link>
		<comments>http://blog.deolen.fr/2009/02/01/je-suis-lami-des-pigeons-rotis/#comments</comments>
		<pubDate>Sun, 01 Feb 2009 12:11:32 +0000</pubDate>
		<dc:creator>Tristan</dc:creator>
				<category><![CDATA[Cuisine]]></category>
		<category><![CDATA[pigeon]]></category>

		<guid isPermaLink="false">http://blog.deolen.fr/?p=78</guid>
		<description><![CDATA[Huit mois sans four &#8230; Si si c&#8217;est possible, du coup on développe d&#8217;autres talents, tel un aveugle qui développe son sens de l&#8217;audition, je suis donc devenu le roi de la poelle ! Mais bon, l&#8217;hiver, c&#8217;est quand même plus gênant, et finalement, ce beau four tout neuf vient tout juste d&#8217;arriver. Cela faisait [...]]]></description>
			<content:encoded><![CDATA[<p>Huit mois sans four &#8230; Si si c&#8217;est possible, du coup on développe d&#8217;autres talents, tel un aveugle qui développe son sens de l&#8217;audition, je suis donc devenu le roi de la poelle ! Mais bon, l&#8217;hiver, c&#8217;est quand même plus gênant, et finalement, ce beau four tout neuf vient tout juste d&#8217;arriver. Cela faisait si longtemps que j&#8217;ai décidé de me faire plaisir, et le premier à en faire les frais, ce sont les pigeons !</p>
<p>Le pigeon, c&#8217;est comme le cochon, c&#8217;est bon. A tous ceux qui ne connaissent pas trop cette volaille: cela n&#8217;a rien à voir avec du poulet ! La chair est plus colorée, la texture plus fondante. Il y a plein de façons de le cuisiner, mais celle que j&#8217;adore est le pigeon simplement rôti au pain à l&#8217;ail.</p>
<p><span id="more-78"></span></p>
<p>Pour obtenir des pigeons, deux méthodes. La première est de se pointer sur le parvis de notre dame avec une carabine. Là il faut alors être assez prompt, non pas pour viser le pigeon, mais pour détaler suffisament rapidement pour pas vous faire coffrer. Remarquez, des poulets et des pigeons dans un panier à salade, ça fait un beau plat. Si ce parcours sportif ne vous sied pas, il reste le marché, où l&#8217;on trouve auprès de la plupart des vendeurs de volaille la bestiole recherchée. En général il faut prévoir 1 pigeon par personne (~ 6 €).</p>
<p>Après, rien de plus simple: une noix de beurre à l&#8217;intérieur, une noix de beurre dessus, un peu de sel et de poivre, et ça y&#8217;est, le pigeon est prêt ! On peut éventuellement le larder pour qu&#8217;il soit un peu moins sec, mais restons simple, c&#8217;est tout aussi bon.</p>
<p>Et le petit truc en plus que j&#8217;adore c&#8217;est le pain à l&#8217;ail: il faut du pain bien sec (peut sécher en quelques heures si on met le pain sur un radiateur tiède). Puis sur chaque tartine, on y écrase une gousse d&#8217;ail. Il faut alors placer une tartine <strong>sous </strong>chaque pigeon (alors que pour le poulet on peut le mettre dedans). Ainsi, il ne ne cuira pas trop, et récupèrera le jus.</p>
<p>Mettre le tout au four à 200°, cuisson 30mn, il faut juste penser à les retourner au bout de 20mn (en les laissant toujours reposer sur le pain). En fin de cuisson, enlever pigeons et pain, déglacer avec une lichette de vin blanc pour récupérer les sucs. Pour l&#8217;accompagnement, c&#8217;est libre: carottes, pommes de terres, gratin dauphinois, &#8230;  miam <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>P.S: je n&#8217;ai pas mis de photo car j&#8217;attends que vous m&#8217;offriez un 40D <img src='http://blog.deolen.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ! En attendant, admirez: <a title="photo pigeon" href="http://tinyurl.com/d39hl5"> photo plat</a> (bon, ok, c&#8217;est pas du meilleurs goût !)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deolen.fr/2009/02/01/je-suis-lami-des-pigeons-rotis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sauvegarde des données</title>
		<link>http://blog.deolen.fr/2009/01/14/sauvegarde-des-donnees/</link>
		<comments>http://blog.deolen.fr/2009/01/14/sauvegarde-des-donnees/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 19:16:20 +0000</pubDate>
		<dc:creator>Tristan</dc:creator>
				<category><![CDATA[Divers]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[comparatif]]></category>
		<category><![CDATA[dropbox]]></category>
		<category><![CDATA[jungledisk]]></category>
		<category><![CDATA[mozy]]></category>
		<category><![CDATA[s3]]></category>
		<category><![CDATA[sauvegarde]]></category>

		<guid isPermaLink="false">http://blog.deolen.fr/?p=32</guid>
		<description><![CDATA[Il y a quelque temps, un couple d&#8217;amis s&#8217;est fait cambrioler. Ce n&#8217;était pas le petit cambriolage. Tout est parti: hifi, bijoux, informatique, voiture, &#8230; Bref, le truc qu&#8217;on ne souhaite à personne, même si votre voleur assureur vous a certifié que tout serait couvert par l&#8217;assurance&#8230; Tout vous avez dit ? Pas vraiment &#8230; [...]]]></description>
			<content:encoded><![CDATA[<p>Il y a quelque temps, un couple d&#8217;amis s&#8217;est fait cambrioler. Ce n&#8217;était pas le petit cambriolage. Tout est parti: hifi, bijoux, informatique, voiture, &#8230; Bref, le truc qu&#8217;on ne souhaite à personne, même si votre <del>voleur</del> assureur vous a certifié que tout serait couvert par l&#8217;assurance&#8230; Tout vous avez dit ? Pas vraiment &#8230; La chose la plus terrible était en fait toutes les photos stockées sur disque dur. Les photos des enfants, leurs premiers pas, des souvenirs que l&#8217;on pensait gravés à jamais sur support numérique&#8230;</p>
<p>Bref, c&#8217;est suite à ça que je me suis rendu compte à quel point le backup était important. Je me disais toujours &laquo;&nbsp;oui oui, c&#8217;est vrai, il faut que je backup&nbsp;&raquo;. Mais ça trainait. On pense toujours que ce genre d&#8217;aventure n&#8217;arrive qu&#8217;aux autres. On pense toujours qu&#8217;on peut passer à travers les mailles du filet de la malchance. Mais quand le cambriolage, l&#8217;incendie, le crash disk survient, et bien &#8230; c&#8217;est trop tard ! Aucun signe avant-coureur ! Bref, leur petite histoire m&#8217;a sacrément motivé pour rechercher une solution de backup !</p>
<p>Je me suis penché sur 3 solutions:</p>
<p class="style:text-align: center;" style="text-align: center;"><a href="http://mozy.com"><img class="size-full wp-image-33 aligncenter" title="mozy" src="http://blog.deolen.fr/wp-content/uploads/2009/01/mozy.png" alt="mozy" width="165" height="42" /></a><a href="http://aws.amazon.com/s3"><img class="aligncenter" src="http://blog.deolen.fr/wp-content/uploads/2009/01/amazons31.png" alt="Amazon S3" width="179" height="89" /></a><a href="http://www.getdropbox.com"><img class="aligncenter" src="http://blog.deolen.fr/wp-content/uploads/2009/01/dropbox.png" alt="dropbox" width="173" height="64" /></a></p>
<p><span id="more-32"></span></p>
<p><a href="http://mozy.com"><img class="alignleft size-full wp-image-33" title="mozy" src="http://blog.deolen.fr/wp-content/uploads/2009/01/mozy.png" alt="mozy" /></a>mozy fournit un petit logiciel à installer sur le poste à sauvegarder. On configure dans ce logiciel les différents répertoires à sauvegarder. Puis ensuite, tout se déroule tout seul. A heures régulières, le soft détecte les changements et les envoie sur le serveur. Le point noir que j&#8217;avais vu est qu&#8217;avant de commencer la sauvegarde proprement dite, Mozy fait de longs traitements pour en théorie optimiser le transfert. Mais pour les fichiers très volumineux (plusieurs centaines de Mo), ces traitements n&#8217;en finissent pas.</p>
<p>Ce que je trouvais intéressant de leur offre &#8216;Home&#8217; était la facilité de calcul du prix: 4.95 $ (soit 3.75 €) par mois pour stockage illimité. J&#8217;ai cherché la petite astérisque (vous savez, celle qu&#8217;on a tendance à louper sur les contrats des assurances) pour voir si c&#8217;était réellement illimité, je n&#8217;ai trouvé aucune restriction. Étonnant quand on voit que la version pro facture 0.50 $ / Go. Mais bon &#8230; Si quelqu&#8217;un a des infos sur ce point, je suis preneur.</p>
<p>Les points négatifs identifiés: client disponible seulement sur Windows &amp; Mac, et mono-poste. Pour un deuxième poste, il faut repayer 4.95 $.</p>
<p>Ces points négatifs ne me paraissaient pas trop embêtant: il suffisait que je monte les disques de mes différents serveurs sur mon serveur Windows, et le tour était joué: windows monoposte, 5$/mois illimité, banco !</p>
<p>Je me suis donc lancé dans le paiement en ligne. Et pour une raison inconnue, il a échoué (si si, le solde de mon compte était positif pour une fois !). J&#8217;ai essayé de contacter le support, qui n&#8217;a pas pu m&#8217;aider, il semblait y avoir des problèmes avec les cartes européennes.</p>
<p>Pas de bol !</p>
<p><a href="http://aws.amazon.com/s3"><img class="alignleft size-full wp-image-33" title="Amazon S3" src="http://blog.deolen.fr/wp-content/uploads/2009/01/amazons31.png" alt="Amazon S3" /></a>Je me suis alors tourné vers Amazon S3. Le premier abord n&#8217;est pas très attirant: pas de logiciel proposé, c&#8217;est avant tout un service, à nous de nous débrouiller pour trouver un soft. De plus, d&#8217;après <a href="http://aws.amazon.com/s3/#pricing">l&#8217;offre tarifaire</a> il est assez dur d&#8217;évaluer le coût réel qui nous sera facturé :</p>
<ul>
<li>Stockage: 0,14 € / Go / mois</li>
<li>Transfert: 0,08 € / Go transferé vers Amazon</li>
<li>Requêtes: 0,01 € / requête</li>
</ul>
<p>D&#8217;après ces chiffres, on comprends qu&#8217;il y a un cout initial de transfert, puis un coût de stockage, quand aux nombre de requêtes, il est très difficile de les évaluer.</p>
<p>Ca, c&#8217;était le coté un peu réfrigérant d&#8217;Amazon S3.</p>
<p>Si on va un peu plus loin, on peut estimer que par exemple, pour sauvegarder 20Go, cela revient à environ 1,60 € de transfert initial plus 3 € par mois de stockage (plus qq centimes pour les requêtes). C&#8217;est quand même un prix intéressant ! De plus, il n&#8217;y a plus de notion de monoposte. Amazon S3 propose un espace de stockage, après, le reste nous regarde.</p>
<p>Coté logiciels, l&#8217;offre est vaste, il existe une <a href="http://www.google.fr/search?q=client+amazon+s3">multitude de softs</a>, que ce soit pour windows, mac, linux, pour smartphones, etc&#8230; Néanmoins, l&#8217;une est particulièrement répandue: <a href="http://www.jungledisk.com">JungleDisk</a>.</p>
<p>Le logiciel fonctionne sous windows, linux, et mac. Il dispose à la fois d&#8217;une interface conviviale (elle a été énormément améliorée depuis la version 2) qui permet de sélectionner les répertoires à sauvegarder, et qui permet de définir une fréquence de backup. A chaque nouveau backup, l&#8217;outil n&#8217;envoie vers le serveur que ce qui a été modifié depuis la dernière fois bien sûr. Il dispose également d&#8217;une version en ligne de commande qui permet éventuellement de scripter l&#8217;outil. A noter également qu&#8217;il y a des options supplémentaires possibles via le fichier de config.</p>
<p>L&#8217;outil est néanmoins payant. 15€ dans sa version de base. Si on veut passer à la version supérieure (JungleDisk Plus), il faut payer 1€ / mois. La version supérieure n&#8217;est intéressante que si l&#8217;on a de très gros fichiers à sauvegarder, car elle permet d&#8217;interrompre et reprendre un chargement, elle est également capable d&#8217;identifier des portions qui ont été modifiées dans ce fichier. Mais pour mon besoin, la version de base est tout à fait satisfaisante.</p>
<p>Pour plus de détails sur l&#8217;offre JungleDisk et des captures d&#8217;écran, je vous recommande <a href="http://case.oncle-tom.net/2008/05/27/sus-aux-disques-durs-sauvegarder-ses-donnees-avec-amazon-s3-et-jungledisk/">l&#8217;article d&#8217;Oncle Tom</a>.</p>
<p><a href="http://www.getdropbox.com"><img class="alignleft size-full wp-image-33" title="DropBox" src="http://blog.deolen.fr/wp-content/uploads/2009/01/dropbox.png" alt="DropBox" /></a><br />
Dropbox se rapproche de mozy dans le sens où il s&#8217;agit d&#8217;une offre packagée, incluant le logiciel client et le service de stockage. Le logiciel est très ergonomique. Pour s&#8217;en faire une idée, allez sur leur <a href="http://www.getdropbox.com">site</a>, et cliquez sur &laquo;&nbsp;watch the video&nbsp;&raquo;. On peut notamment voir en temps réel dans l&#8217;explorateur quels sont les fichiers qui sont à synchroniser (un peu comme TortoiseSvn).</p>
<p>Ergonomique, mais encore incomplet fonctionnellement: Dropbox ne permet de sauvegarder qu&#8217;un seul répertoire ! En fait, Dropbox est probablement plus orienté synchronisation de données sur plusieurs postes, plutôt que backup. Un répertoire est créé (&laquo;&nbsp;My Dropbox&nbsp;&raquo;), et tous les fichiers qui sont placés dans ce répertoire seront automatiquement sauvegardés. Si un autre poste est également relié au même compte Dropbox, alors les données sont synchronisées.</p>
<p>En réalité, le stockage est réalisé sur Amazon S3. Mais le paiement passe par le site Dropbox, qui propose un espace de 50 Go pour 7,60 € / mois.</p>
<h3>Conclusion</h3>
<p>J&#8217;ai opté pour Amazon S3 plus JungleDisk qui me permettent une grande flexibilité dans l&#8217;archivage de mes différents postes. L&#8217;offre mozy semble très intéressante pour de gros volumes (&gt; 50 Go), avec le défaut néanmoins de ne pas proposer de client Linux.</p>
<p>Je n&#8217;ai pas évalué l&#8217;offre <a href="https://www.google.com/accounts/PurchaseStorage">Google</a> car inexistante à l&#8217;époque où j&#8217;avais fait mes tests.</p>
<p>N&#8217;hésitez pas à me faire tout retour d&#8217;expérience, non pas que je pense être cambriolé, mais &#8230; on ne sait jamais !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deolen.fr/2009/01/14/sauvegarde-des-donnees/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Installation d&#8217;un serveur subversion sur Ubuntu</title>
		<link>http://blog.deolen.fr/2009/01/11/installation-dun-serveur-subversion-sur-ubuntu/</link>
		<comments>http://blog.deolen.fr/2009/01/11/installation-dun-serveur-subversion-sur-ubuntu/#comments</comments>
		<pubDate>Sun, 11 Jan 2009 21:42:51 +0000</pubDate>
		<dc:creator>Tristan</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[vhost]]></category>

		<guid isPermaLink="false">http://blog.deolen.fr/?p=9</guid>
		<description><![CDATA[Certes, on trouve plein de doc sur le sujet un peu partout, que ce soit sur le site de subversion, sur les sites de Ubuntu, ou des forums alternatifs. Et pourtant, j&#8217;ai quand même eu du mal à rassembler toutes les billes, car il existe plusieurs solutions (apache, svnserve), basées ou non sur SSL, avec [...]]]></description>
			<content:encoded><![CDATA[<p>Certes, on trouve plein de doc sur le sujet un peu partout, que ce soit sur le site de subversion, sur les sites de Ubuntu, ou des forums alternatifs. Et pourtant, j&#8217;ai quand même eu du mal à rassembler toutes les billes, car il existe plusieurs solutions (apache, svnserve), basées ou non sur SSL, avec différents moyens d&#8217;authentification, avec des procédures plus ou moins différentes suivant les OS, gérées en vhost ou non, &#8230;</p>
<p>Mon besoin: avoir un virtual host (https://svn.domaine.fr) dans lequel je peux y gérer plusieurs repository svn (https://svn.domaine.fr/projet1, etc&#8230;). Le tout hébergé sur un serveur Ubuntu 8.04 (Hardy).</p>
<p>J&#8217;ai finalement adopté la solution basée sur apache2, et ce fut plus simple que certaines manips que j&#8217;ai vu sur certains forums.</p>
<p><span id="more-9"></span></p>
<p>J&#8217;utiliserai l&#8217;arborescence suivante pour mes dépots svn:</p>
<pre>/var---svn         ; répertoire de base contenant tous les dépots
        +-projet1  ; repository du projet 1
        +-projet2  ; repository du projet 2
                   ; etc...</pre>
<h3>Création des repositories subversion</h3>
<p>Installer svn:</p>
<pre><code>sudo apt-get install subversion</code></pre>
<p>Création d&#8217;un répertoire qui contiendra tous les repositories:</p>
<pre><code>mkdir /var/svn</code></pre>
<p>Puis création d&#8217;un repository pour chaque projet:</p>
<pre><code>svnadmin create /var/svn/projet1</code></pre>
<h3>Installation d&#8217;apache et SSL</h3>
<pre>sudo apt-get install apache2 openssl</pre>
<p>Activer le mod ssl et créer un certificat (validité 1 an dans l&#8217;exemple ci-dessous):</p>
<pre><code>sudo a2enmod ssl
sudo openssl req -x509 -nodes -days <span class="nu0">365</span> -newkey rsa:<span class="nu0">1024</span> \
                   -out /etc/apache2/server.crt -keyout /etc/apache2/server.key</code></pre>
<p>Répondre aux questions posées, voici un exemple de réponses:</p>
<pre><code>FR
FRANCE
Bordeaux
Ma compagnie fictive
Idem
svn.domaine.fr
nom@mail.fr</code></pre>
<p>Puis modifier les droits du certificat:</p>
<pre><code>sudo chmod go-rwx /etc/apache2/server.key</code></pre>
<h3>Lien entre apache et svn</h3>
<p>Il faut installer le mod dav_svn:</p>
<pre><code>sudo apt-get install libapache2-svn</code></pre>
<p>On n&#8217;éditera pas /etc/apache2/mods-available/dav_svn.conf, on mettra les réglages directement dans le fichier vhost afin de bénéficier de la clause ServerName (sinon les réglages svn seraient appliqués pour tous les vhosts).</p>
<p>Si on veut un accès protégé, il faut créer un utilisateur svn &#8216;toto&#8217;:</p>
<pre><code>sudo htpasswd -cs /etc/apache2/dav_svn.passwd toto</code></pre>
<p>Puis pour ajouter d&#8217;autres utilisateurs, remplacer &#8216;-cs&#8217; par &#8216;-s&#8217;.</p>
<p>Modifier l&#8217;appartenance de certains répertoires pour qu&#8217;apache puisse y accéder:</p>
<pre><code>sudo chown www-data:www-data /etc/apache2/dav_svn.passwd
sudo chown -R www-data:www-data /var/svn</code></pre>
<p>Activer si ce n&#8217;est déjà fait le module dav_svn:</p>
<pre><code>sudo a2enmod dav_svn</code></pre>
<p>Créer ensuite un virtual host, dans mon exemple il s&#8217;agit de https://svn.domaine.fr. Editer le fichier /etc/apache2/sites-available/svn, puis y coller:</p>
<pre><code>NameVirtualHost *:443

&lt;VirtualHost *:443&gt;

    ServerName svn.domaine.fr
    SSLEngine on
    SSLCertificateFile /etc/apache2/server.crt
    SSLCertificateKeyFile /etc/apache2/server.key

    &lt;Location / &gt;
      DAV svn
      SVNParentPath /var/svn
      AuthType Basic
      AuthName "Subversion Repository"
      AuthUserFile /etc/apache2/dav_svn.passwd
      Require valid-user
    &lt;/Location&gt;
&lt;/VirtualHost&gt;</code></pre>
<p>(Les 4 dernieres directives servent à protéger l&#8217;accès. Les enlever pour un accès public).</p>
<p>Puis l&#8217;activer:</p>
<pre><code>sudo a2ensite svn</code></pre>
<p>Puis redémarrer apache:</p>
<pre><code>sudo /etc/init.d/apache2 reload</code></pre>
<p>Ignorer les warnings &laquo;&nbsp;Could not reliably determine etc&#8230;&nbsp;&raquo;. Par contre, si un message d&#8217;erreur concernant les ports apparait, éditer alors le fichier /etc/apache2/sites-enabled/000-default, et remplacer les &#8216;*&#8217; par &#8216;*:80&#8242; (2 occurences). S&#8217;il y a d&#8217;autres fichiers dans ce meme répertoire, appliquer la meme modif.</p>
<h3>Et voilà !</h3>
<p>Vous pouvez maintenant vous rendre avec votre navigateur à l&#8217;adresse suivante: https://svn.domaine.fr/projet1</p>
<p>Et pour créer de nouveaux repositories, il suffira juste de taper:</p>
<pre><code>sudo svnadmin create /var/svn/nouveauprojet
sudo chown -R www-data:www-data /var/svn/nouveauprojet</code></pre>
<p>Le navigateur vous proposera d&#8217;ajouter une exception pour le certificat de ce site.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deolen.fr/2009/01/11/installation-dun-serveur-subversion-sur-ubuntu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Et hop, c&#8217;est parti !</title>
		<link>http://blog.deolen.fr/2009/01/11/et-hop-cest-parti/</link>
		<comments>http://blog.deolen.fr/2009/01/11/et-hop-cest-parti/#comments</comments>
		<pubDate>Sun, 11 Jan 2009 18:44:40 +0000</pubDate>
		<dc:creator>Tristan</dc:creator>
				<category><![CDATA[Divers]]></category>
		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://blog.deolen.fr/?p=5</guid>
		<description><![CDATA[Bon, ça y&#8217;est, je me lance enfin dans l&#8217;aventure du blog. Je voyais fleurir autour de moi un bon nombre de sites perso, mais j&#8217;avais du mal à me laisser aller à cet engouement. Je résistais avec vaillance (si si !) aux slogans du type &#171;&#160;ouaiiiis, si t&#8217;es cool t&#8217;as ton blooooog&#160;&#187; ! Mais finalement [...]]]></description>
			<content:encoded><![CDATA[<p>Bon, ça y&#8217;est, je me lance enfin dans l&#8217;aventure du blog. Je voyais fleurir autour de moi un bon nombre de sites perso, mais j&#8217;avais du mal à me laisser aller à cet engouement. Je résistais avec vaillance (si si !) aux slogans du type &laquo;&nbsp;ouaiiiis, si t&#8217;es cool t&#8217;as ton blooooog&nbsp;&raquo; ! Mais finalement je suis peut-être en train de faiblir !</p>
<p><span id="more-5"></span>Non pas que ma vie ait un quelconque intérêt à être exposée sur le web. Mais c&#8217;est juste que parfois, je découvre des choses que j&#8217;ai envie de partager. Que ce soit une solution à un problème technique, ou que ce soit la découverte d&#8217;un super endroit.</p>
<p>Mon problème est que je me passionne pour toutes sortes de choses, du coup Internet est devenu mon plus grand malheur: une porte ouverte sur la connaissance illimitée (&lt;/envolée lyrique&gt;). Donc au même titre que je peux bénéficier de l&#8217;information fournie par d&#8217;autres internaute, il me semble logique et intéressant de participer à cette base de connaissances.</p>
<p>Bon, ça, c&#8217;est la théorie. En pratique, ce qui m&#8217;a toujours freiné pour la création d&#8217;un blog c&#8217;est le temps. J&#8217;ai peur de ne pas avoir le courage de passer suffisament de temps pour faire vivre ce blog.  C&#8217;est pourquoi je vois ce blog plus comme un &laquo;&nbsp;bloc-notes&nbsp;&raquo;: je compte ne pas trop m&#8217;embarrasser de la forme, et rédiger mes remarques de manière assez synthétiques.</p>
<p>On verra si je peux tenir le cap !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deolen.fr/2009/01/11/et-hop-cest-parti/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

