<?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>Web, je vous dis web &#187; django</title>
	<atom:link href="http://blog.o2sources.com/tag/django/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.o2sources.com</link>
	<description>le blog d'O2Sources</description>
	<lastBuildDate>Thu, 01 Jul 2010 08:38:23 +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>Géolocaliser des utilisateurs sur l&#8217;IP en Python</title>
		<link>http://blog.o2sources.com/2009/10/14/geolocaliser-des-utilisateurs-sur-lip-en-python.html</link>
		<comments>http://blog.o2sources.com/2009/10/14/geolocaliser-des-utilisateurs-sur-lip-en-python.html#comments</comments>
		<pubDate>Wed, 14 Oct 2009 13:43:28 +0000</pubDate>
		<dc:creator>Damien</dc:creator>
				<category><![CDATA[développement]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[geolite]]></category>
		<category><![CDATA[geolocalisation]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[maxmind]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.o2sources.com/?p=520</guid>
		<description><![CDATA[Depuis quelques temps, plusieurs clients nous demandent de pouvoir géolocaliser leurs visiteurs de manière plus ou moins précise.
La plupart du temps, leur but est simplement d&#8217;afficher une carte centrée sur la localisation (approximative) de l&#8217;utilisateur.
Pour mener cela à bien, nous avons décidé d&#8217;utiliser Geolite Country.
Celui-ci permet de géolocaliser l&#8217;utilisateur en fonction de son ip sur [...]]]></description>
			<content:encoded><![CDATA[<p>Depuis quelques temps, plusieurs clients nous demandent de pouvoir géolocaliser leurs visiteurs de manière plus ou moins précise.<br />
La plupart du temps, leur but est simplement d&#8217;afficher une carte centrée sur la localisation (approximative) de l&#8217;utilisateur.</p>
<p>Pour mener cela à bien, nous avons décidé d&#8217;utiliser <a href="http://www.maxmind.com/app/geolitecountry">Geolite Country</a>.<br />
Celui-ci permet de géolocaliser l&#8217;utilisateur en fonction de son ip sur la base du Pays. Pour une recherche plus affinée, les services sont payants. Mais le client désire uniquement centrer sur le pays de l&#8217;utilisateur. L&#8217;offre gratuite est donc amplement suffisante.</p>
<p>L&#8217;application étant en Python et ayant décidé d&#8217;utiliser la base binaire, j&#8217;ai donc installé la librairie <a href="http://code.google.com/p/pygeoip/">pygeoip</a>.<br />
Son utilisation est particulièrement simple.</p>
<pre class="brush: python;">gmaps = urllib.urlopen('http://maps.google.com/maps/geo?q=%s&amp;output=csv' % urllib.quote(country)).read().rsplit(',')</pre>
<p>Le fichier GeoIP.dat est la base de données binaire, accessible sur GeoLite via ce <a href="http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz">lien direct</a>.<br />
Ainsi notre variable &laquo;&nbsp;country&nbsp;&raquo; est un string contenant le nom du pays. Ici &laquo;&nbsp;France&nbsp;&raquo;.</p>
<p>Il faut par la suite obtenir la latitude et la longitude de ce pays. Pour cela, <a href="http://code.google.com/apis/maps/">Google Maps API</a> est particulièrement utile.</p>
<pre class="brush: python;">gi = pygeoip.GeoIP('lib/GeoIP.dat')&lt;br /&gt;
country = gi.country_name_by_name('o2sources.com')</pre>
<p>Notre variable &laquo;&nbsp;gmaps&nbsp;&raquo; contiendra ainsi un tableau pour lequel les deux derniers éléments sont respectivement la latitude et la longitude.<br />
Il n&#8217;y a plus qu&#8217;à afficher notre carte Google Maps centrée sur des données <img src='http://blog.o2sources.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Et puisque du code sans son contexte est d&#8217;une utilité moyenne, voici la vue permettant d&#8217;obtenir ces données</p>
<pre class="brush: python;">from django.shortcuts import render_to_response
from django.template import RequestContext

import pygeoip
import urllib

def home(request):
  gi = pygeoip.GeoIP('lib/GeoIP.dat')
  country = gi.country_name_by_name(request.META['REMOTE_ADDR'])
  gmaps = urllib.urlopen('http://maps.google.com/maps/geo?q=%s&amp;output=csv' % urllib.quote(country)).read().rsplit(',')
  return render_to_response('centers/home.html', { 'country': country, 'latitude': gmaps[2], 'longitude': gmaps[3] }, context_instance=RequestContext(request))</pre>
<p>Et dans notre template nous n&#8217;avons plus qu&#8217;à traiter ces données comme nous le désirons. Dans mon cas en affichant une carte Google Maps.<br />
Mais vos besoins peuvent varier et les possibilitées sont quasiment illimitées.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.o2sources.com/2009/10/14/geolocaliser-des-utilisateurs-sur-lip-en-python.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Déployer une application Django avec Capistrano</title>
		<link>http://blog.o2sources.com/2009/08/26/deployer-une-application-django-avec-capistrano.html</link>
		<comments>http://blog.o2sources.com/2009/08/26/deployer-une-application-django-avec-capistrano.html#comments</comments>
		<pubDate>Wed, 26 Aug 2009 10:03:45 +0000</pubDate>
		<dc:creator>Damien</dc:creator>
				<category><![CDATA[développement]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[déploiement]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[dry]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.o2sources.com/?p=491</guid>
		<description><![CDATA[Chez O2Sources on aime tout ce qui permet d&#8217;améliorer la productivité. Et si en prime ça permet d&#8217;éviter des erreurs, on adore !
Malheureusement jusqu&#8217;à maintenant, nous déployions toutes nos applications &#171;&#160;à la main&#160;&#187;, en FTP.
Mais grâce à Capistrano, nous remédions maintenant à cela en automatisant le déploiement de nos applications, afin de gagner du temps [...]]]></description>
			<content:encoded><![CDATA[<p>Chez O2Sources on aime tout ce qui permet d&#8217;améliorer la productivité. Et si en prime ça permet d&#8217;éviter des erreurs, on adore !<br />
Malheureusement jusqu&#8217;à maintenant, nous déployions toutes nos applications &laquo;&nbsp;à la main&nbsp;&raquo;, en FTP.<br />
Mais grâce à <a href="http://capify.org">Capistrano</a>, nous remédions maintenant à cela en automatisant le déploiement de nos applications, afin de gagner du temps et surtout, d&#8217;éviter les erreurs ou les oublis.</p>
<p>Capistrano est un outil permettant d&#8217;automatiser le déploiement des applications développé en Ruby.<br />
Mais il est utilisable avec toutes vos applications. Qu&#8217;elles soient développées en Ruby, en PHP, en Python et même, si vous êtes un peu fou, en Java.<br />
Dans l&#8217;exemple que je vais donner ci-dessous, l&#8217;application est développée en Python avec Django. Et nous avions une problématique majeure : nous désirons pouvoir déployer sur le serveur de développement et/ou sur le serveur de production sans avoir deux tâches différentes (afin d&#8217;être DRY évidemment).</p>
<p>Dans un dossier nommé <em>deployment</em> à la base de notre application, j&#8217;ai créé deux fichiers.<br />
<strong>deploy</strong><br />
Il s&#8217;agit d&#8217;un script bash, qui permettra d&#8217;exécuter le processus sans avoir à taper &laquo;&nbsp;cap &#8230;&nbsp;&raquo;.<br />
En voici le contenu.<br />
<code>#!/bin/bash<br />
ENV=$1 cap deploy -f deployment/deploy.rb</code></p>
<p>Vous pouvez noter que avant d&#8217;exécuter le script, je définis une variable d&#8217;environnement à la valeur du premier argument passé en paramètres.<br />
Cela nous permettra de choisir si nous désirons pousser en développement ou en production.</p>
<p>Puis un fichier <strong>deploy.rb</strong>.<br />
Vous pouvez en <a href="http://gist.github.com/175416">voir le contenu complet</a>. Mais je vais également le détailler dans la suite de cet article.</p>
<p>Nous définissons plusieurs valeurs de configuration.<br />
<code>set :deploy_to, {'dev' => '/chemin/vers/le/site/en/developpement', 'prod' => '/chemin/vers/le/site/en/production'}<br />
set :domain, {'dev' => 'host.developpement', 'prod' => 'host.production'}</code></p>
<p>La première variable contient le chemin de notre application, en développement et en production.<br />
Le second contient les hosts de nos serveurs de développement et de production.</p>
<p>Puis nous définissons le serveur sur lequel nous voulons déployer.<br />
<code>ENV['ENV'] = 'dev' if domain[ENV['ENV']].nil?<br />
role :web, domain[ENV['ENV']], :master => true</code></p>
<p>Si le paramètre &laquo;&nbsp;ENV&nbsp;&raquo; est à la valeur &laquo;&nbsp;prod&nbsp;&raquo;, nous déployons en production. Sinon, nous déployons en développement.</p>
<p>Ainsi pour déployer en développement, vous n&#8217;aurez qu&#8217;à appeller votre script bash :<br />
<code>deployment/deploy</code><br />
Et en production, il faudra préciser le paramètre.<br />
<code>deployment/deploy prod</code></p>
<p>Notre tâche capistrano contient ensuite les directives de déploiement.<br />
La tâche deploy:default est appellée automatiquement. Elle fait un svn update, mettant ainsi à jour les fichiers de l&#8217;application.<br />
<code>desc "Updating the repository files in " + ENV['ENV'] + " environment"<br />
task :default do<br />
&nbsp;&nbsp;stream "cd #{deploy_to[ENV['ENV']]}; svn update"<br />
end</code></p>
<p>Nous avons ensuite une seconde tâche qui supprime tous les fichiers .pyc de notre application, afin d&#8217;éviter un quelconque problème de cache avec ceux-ci (ils sont générés automatiquement par Python).<br />
<code>desc "Remove *.pyc files"<br />
task :delpyc do<br />
&nbsp;&nbsp;stream 'cd ' + deploy_to[ENV['ENV']] + ';find . -type f -name "*.pyc" -exec rm -fv {} \;'<br />
end</code></p>
<p>Puis nous mettons à jour la base de données de notre application en faisant un syncdb.<br />
<code>desc "Make sure database is in sync with models"<br />
task :syncdb do<br />
&nbsp;&nbsp;stream "cd #{deploy_to[ENV['ENV']]}; python manage.py syncdb"<br />
end</code></p>
<p>Et enfin, puisque c&#8217;est un projet Django, il faut, afin que les modifications soient prises en compte, recharger Apache.<br />
<code>desc "We reload apache"<br />
task :restart do<br />
&nbsp;&nbsp;stream "/etc/init.d/apache2 reload"<br />
end</code></p>
<p>Nous avons maintenant défini nos tâches. Et comme dit précédemment, la tâche default est exécutée automatiquement.<br />
Mais il faut tout de même définir l&#8217;ordre d&#8217;exécution des tâches. C&#8217;est la que viennent les instructions &laquo;&nbsp;after&nbsp;&raquo;.<br />
<code>after 'deploy', 'deploy:delpyc'<br />
after 'deploy:delpyc', 'deploy:syncdb'<br />
after 'deploy:syncdb', 'deploy:restart'</code></p>
<p>Notre tâche Capistrano fera donc, dans l&#8217;ordre :</p>
<ol>
<li>Un SVN update afin de récupérer la dernière version du projet</li>
<li>Une suppression de tous les fichiers .pyc</li>
<li>Une remise à jour de la base de données</li>
<li>Un rechargement du serveur</li>
</ol>
<p>Pour rappel, vous pouvez <a href="http://gist.github.com/175416">voir la tâche complète et colorisée sur github</a>.</p>
<p>Votre application est à jour. Ici, ça prends 2 minutes chrono. Et on est sur que ça fonctionne (et si ça ne fonctionne pas quand même, cela nous prévient) <img src='http://blog.o2sources.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Et vous, vous déployez vos applications comment ?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.o2sources.com/2009/08/26/deployer-une-application-django-avec-capistrano.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
