Fantomas' side - Entries for the tag bloghttps://blog.fantomas.site/blog/tags/blog/The last entries tagged with blogfrCopyright (c) 2005-2018, Julien FacheFri, 06 Feb 2015 22:40:49 +0000Migration des blogs de Libération.fr sur Zinnia https://blog.fantomas.site/blog/2014/12/05/migration-des-blogs-de-liberation-sur-zinnia/ <img src="/media/cache/6b/66/6b666c5e70bccdf171c1161326a5ba57.jpg" alt="Migration des blogs de Libération.fr sur Zinnia" /> <p>Depuis maintenant 1 an et demi, en tant que développeur, je travaille pour le site internet <a href="http://www.liberation.fr/">Libération.fr</a>, du journal du même nom.</p><p>Les problématiques sont variées et l'exigence technique au rendez-vous. Grâce à une équipe sympathique et compétente, on a le temps et les moyens de faire de la qualité dans notre travail, le tout dans un environnement particulier, celui d'un quotidien national.</p><p>Il y a quelques semaines, suite à de nombreux échanges et écueils techniques, nous avons décidé de migrer les quelques 350 blogs de Libération hébergés chez <a href="http://www.typepad.com/">Typepad</a>, vers une nouvelle plate-forme qui devra être plus adaptée à nos besoins.</p><p>Étant spécialistes Django nous avons donc décidé d'utiliser <a href="http://www.django-blog-zinnia.com/">Zinnia</a>, la solution de blogs développée par mes soins, afin de bénéficier ainsi de mon expertise dans le domaine et du retour d'expérience des centaines de blogs déjà déployés sur cette solution.</p><p>Une des exigences technique, fut de n'avoir qu'une seule instance Django pour faire tourner toutes les instances de blogs. Car il est inenvisageable pour des raisons de maintenance et de ressources, de devoir installer une nouvelle instance Django à chaque ouverture de blog.</p><p>Zinnia étant modulaire et extensible, l'application a donc servi de socle au projet, puis fût paramétrée et enrichie afin de satisfaire aux besoins d'une plate-forme multi-blogs.</p><p>Donc autour de Zinnia, j'ai développé plusieurs applications aux fonctionnalités spécifiques, dont on peut citer :</p><ul><li>le mécanisme pour rendre Zinnia multi-blogs.</li><li>l'éditeur de contenu, basé sur <a href="http://imperavi.com/redactor/">redactor</a>.&#160;</li><li>le gestionnaire de profils publicitaires.</li><li>l'interface d'administration de la plate-forme.</li><li>le processus de migration de Typepad vers Zinnia.</li><li>et un thème personnalisé aux couleurs de Libération.</li></ul><p>Là où je tire une certaine fierté dans la réalisation de ce projet, c'est qu'à aucun moment je n'ai dû modifier le code source de Zinnia pour satisfaire une exigence ou résoudre un problème, tout cela grâce à la modularité du programme. Chose qui arrive assez rarement dans le monde des applications Django, pour qu'on le souligne.</p><p>Pour finir, grâce à cette réalisation, j'ai aussi pu me prouver que le petit programme de blogs, réalisé à titre personnel pour ce site, a bien évolué. <br />Car désormais il peut tout aussi bien servir de blog personnel très simple, que de plate-forme de blogs hautement personnalisée, chose que je n'avais pas forcément en tête en commençant Zinnia il y a maintenant <a href="http://fantomas.willbreak.it/blog/2008/11/16/changement-adresse-migration-django/">presque 6 ans</a>.</p> fantomas42@gmail.com (fantomas)Fri, 05 Dec 2014 20:20:08 +0000https://blog.fantomas.site/blog/2014/12/05/migration-des-blogs-de-liberation-sur-zinnia/DéveloppementLe temps des releases : django-blog-zinnia https://blog.fantomas.site/blog/2010/09/16/le-temps-des-releases-django-blog-zinnia/ <img src="/media/cache/2a/46/2a4621e127ec848eb30eb57f5f3f1fdf.jpg" alt="Le temps des releases : django-blog-zinnia" /> <p>Incroyable, après presque 2 ans d'attente, Zinnia l'application Django propulsant ce blog est enfin publiée sur un dépôt public.&#160;</p><p>Le premier article faisant référence à <a title="Première apparition de django-blog-zinnia." href="/blog/2008/11/16/changement-adresse-migration-django/">Zinnia date en effet du 16 Novembre 2008</a>.</p><p>Beaucoup d'évolutions ont été apportées entre cette première version réalisée à titre personnel et celle qui gère le site actuellement. Ceci explique en partie mon manque d'activité sur le site.</p><p>Au final, j'en ai profité pour mettre à jour le code du site en utilisant la version de développement et refondre le skin du site, un peu trop sombre et vieillissant à mon goût.</p><p>Maintenant, concentrons nous sur notre sujet. Tout d'abord <a title="Code source de django-blog-zinnia" href="http://github.com/Fantomas42/django-blog-zinnia">le code source de Zinnia est disponible sur GitHub</a>, ce qui facilite le travail communautaire, donc si vous voulez participer, forker ou télécharger, aucun problème, vous y êtes même encouragé.</p><p>Lors de la publication du code source, je me suis efforcé de documenter un maximum les fonctionnalités ainsi que l'installation, donc pour présenter le projet je vais me baser sur ces documents.</p><p>Tout d'abord, qu'est-ce-que Zinnia ou django-blog-zinnia exactement ?</p><blockquote><p>Zinnia est une application générique pour gérer un blog à travers un site en Django. Elle a été conçue pour publier des articles et le faire efficacement ! De manière générale toutes les fonctionnalités qui peuvent être fournies par une autre application réutilisable écrite en Django ont été mises de coté. Pourquoi réécrire ce qui a déjà été testé et approuvé par les autres ?</p></blockquote><p>Mais plutôt qu'un long discours, je vais dresser la liste actuelle des fonctionnalités disponibles.</p><ul class="simple"><li>Commentaires</li><li>Flux RSS ou Atom</li><li>Vues par archives</li><li>Vues par catégories et tags</li><li>Détection des articles relatifs</li><li><a title="Possibilités du moteur de recherche." href="http://django-blog-zinnia.com/docs/SEARCH_ENGINES.html">Moteur de recherche avancé</a></li><li>Prépublication et expiration</li><li>Widgets</li><li>Sitemaps</li><li>Protection anti-spam avec Akismet</li><li>API <a title="Qu'est ce que MetaWeblog" href="http://en.wikipedia.org/wiki/MetaWeblog">MetaWeblog</a></li><li>Ping dans les annuaires</li><li>Ping des ressources externes</li><li>Support de Bit.ly, Twitter</li><li>Gestion de Gravatar</li><li>Plugin pour <a title="Django-CMS" href="http://www.django-cms.org/">Django-CMS</a></li><li>Travail collaboratif</li><li>Autocomplétion des tags</li><li>Support des Pingbacks et Trackbacks</li><li>WYMeditor ou TinyMCE pour éditer</li><li>Templates génériques prêts l'emploi</li><li>Utilitaire de conversion depuis WordPress</li></ul><p>&#160;Je dois certainement oublier des petites choses, mais ça commence déjà à faire pas mal. D'ailleurs, si vous avez une idée de ce qui pourrait manquer n'hésitez pas à m'en faire part.</p><p>Une documentation complète et mise à jour se trouve à cette adresse : <a title="Documentation de django-blog-zinnia" href="http://django-blog-zinnia.com/docs/">http://django-blog-zinnia.com/docs/</a><br />Vous trouverez dans cette documentation un lien vers une documentation de l'API, ainsi que le <a title="Définition de code coverage." href="http://en.wikipedia.org/wiki/Code_coverage">code coverage</a> des tests effectués sur l'application. Car bien sûr l'application est testée. Ouf !</p><p>J'ai failli oublier de dire qu'une version de démonstration de l'application se trouvait ici : <a title="Démo de django-blog-zinnia." href="http://django-blog-zinnia.com/blog/">http://django-blog-zinnia.com/blog/</a></p><p>Bon il ne reste plus qu'à écrire des articles ! :)</p> fantomas42@gmail.com (fantomas)Thu, 16 Sep 2010 18:51:12 +0000https://blog.fantomas.site/blog/2010/09/16/le-temps-des-releases-django-blog-zinnia/DéveloppementStop aux spams sur django.contrib.comments https://blog.fantomas.site/blog/2009/04/16/stop-aux-spams-sur-djangocontribcomments/ <img src="/media/cache/43/84/43846421f58a2c823750cc6f683f6c70.jpg" alt="Stop aux spams sur django.contrib.comments" /> <p>Depuis quelques jours, les formulaires de commentaires fournis par l'application <strong>django.contrib.comments</strong> dans la distribution de Django, sont devenus vulnérables aux spams.</p><p>L'application <strong>comments</strong> contient par défauts plusieurs sécurités pour éviter le spamming, comme un <em>honeypot</em> et la vérification du temps de saisie du commentaires.</p><p>Malgré cela les équipes de spammer sont très réactives, et coder un bot spécifique pour les sites django utilisant ce système de commentaires, rend tous ces sites vulnérables.</p><p>En parallèle de cela, dans la version 1.1b de Django, l'application <strong>comments</strong> acquiert une nouvelle fonctionnalité, qu'est la modération automatique. L'envois de mails en cas de commentaires, et aussi prise en charge.</p><p>J'en ai donc profité pour développer une protection contre le spam plus efficace basée sur <strong>Akismet</strong> à partir de cette nouvelle fonctionnalité.</p><pre>"""Moderator of Entry comments<br />&#160;&nbsp; Based on Akismet for checking spams<br />&nbsp;&nbsp; Need to override the default Moderator,<br />&nbsp;&nbsp; for getting request in parameters."""<br />from django.conf import settings<br />from django.utils.encoding import smart_str<br />from django.contrib.sites.models import Site<br />from django.db.models import signals<br />from django.contrib import comments<br />from django.contrib.comments.signals import comment_will_be_posted<br />from django.contrib.comments.moderation import Moderator<br />from django.contrib.comments.moderation import CommentModerator<br /><br />from django.conf.settings import MAIL_COMMENT<br />from django.conf.settings import AKISMET_COMMENT<br /><br />AKISMET_API_KEY = getattr(settings, 'AKISMET_API_KEY', '')<br /><br />class EntryCommentModerator(CommentModerator):<br />&nbsp;&nbsp;&nbsp; """Moderate the comment of Entry"""<br />&nbsp;&nbsp;&nbsp; email_notification = MAIL_COMMENT<br />&nbsp;&nbsp;&nbsp; enable_field = 'comment_enabled'<br /><br />&nbsp;&nbsp;&nbsp; def email(self, comment, content_object):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if comment.is_public:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(EntryCommentModerator, self).email(comment, content_object)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; def moderate_akismet(self, comment, content_object, request):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; """Need to pass Akismet test"""<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not AKISMET_COMMENT:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return False<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from akismet import Akismet<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from akismet import APIKeyError<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; akismet = Akismet(key=AKISMET_API_KEY,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blog_url='http://%s/' % Site.objects.get_current().domain)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if akismet.verify_key():<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; akismet_data = {'user_ip': request.META.get('REMOTE_ADDR', ''),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'user_agent': request.META.get('HTTP_USER_AGENT', ''),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'referrer': request.META.get('HTTP_REFERER', 'unknown'),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'permalink': content_object.get_absolute_url(),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'comment_type': 'comment',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'comment_author': comment.userinfo.get('name', ''),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'comment_author_email': comment.userinfo.get('email', ''),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'comment_author_url': comment.userinfo.get('url', '')}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return akismet.comment_check(smart_str(comment.comment),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data=akismet_data,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; build_data=True)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise APIKeyError("Your Akismet API key is invalid.")<br /><br /><br />class EntryModerator(Moderator):<br />&nbsp;&nbsp;&nbsp; """Moderator for Entry"""<br /><br />&nbsp;&nbsp;&nbsp; def connect(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; comment_will_be_posted.connect(self.pre_save_moderation, sender=comments.get_model())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signals.post_save.connect(self.post_save_moderation, sender=comments.get_model())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /><br />&nbsp;&nbsp;&nbsp; def pre_save_moderation(self, sender, comment, request, **kwargs):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; """Overriding the existing method by passing request to allow"""<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(EntryModerator, self).pre_save_moderation(sender, comment, **kwargs)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; moderation_class = self._registry[comment.content_type.model_class()]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if moderation_class.moderate_akismet(comment, comment.content_object, request):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; comment.is_public = False<br /><br /><br /><br />moderator = EntryModerator()</pre><p>Il suffit juste d'installer le module Akismet pour Python, et cela devrais fonctionner en définissant sa clef d'API Akismet.</p><p>Bon par contre, on remarque de suite qu'il est dommage de devoir écrire une nouvelle classe <em>Moderator</em>, pour pouvoir récupérer et passer le context, c'est peu pratique en effet, surtout que <strong>comments</strong> peux le gérer par défaut avec le signal <strong>comment_will_be_posted</strong>.</p><p>Mais à priori cela risque de changer si on en regarde le ticket suivant, prévu pour la version finale de Django 1.1 : <a title="TIcket 10878 sur la modération de commentaires." href="http://code.djangoproject.com/ticket/10878">Ticket 10878, projet Django</a></p><p>Donc une réécriture du code sera certainement nécessaire à la sortie de cette version, qui commence à se faire attendre....</p><p>Pour plus d'informations : <a title="Documentation sur la modération de django.contrib.comments" href="http://docs.djangoproject.com/en/dev/ref/contrib/comments/moderation/">Documentation sur la modération</a></p> fantomas42@gmail.com (fantomas)Wed, 15 Apr 2009 23:14:47 +0000https://blog.fantomas.site/blog/2009/04/16/stop-aux-spams-sur-djangocontribcomments/DéveloppementExpériencesComment passer de Wordpress à Django https://blog.fantomas.site/blog/2008/11/24/comment-passer-de-wordpress-django/ <p><strong>Wordpress</strong> c'est très bien, mais ca devient peu devenir vite une machine à gaz. Mon hébergement gratuit et mutualisé chez 1and1 étant finis, je dois migrer sur un nouveau serveur, et PHP, pour moi c'est révolu, autant passer à Django, et décrire la marche à suivre.</p> <p><a href="http://fantomas.willbreak.it/migration-wordpress-django" title="Migration de Wordpress vers Django">Consulter le tutorial</a></p> fantomas42@gmail.com (fantomas)Mon, 24 Nov 2008 21:01:44 +0000https://blog.fantomas.site/blog/2008/11/24/comment-passer-de-wordpress-django/DéveloppementChangement d'adresse et migration sur Django https://blog.fantomas.site/blog/2008/11/16/changement-adresse-migration-django/ <p>Cela va faire 3 ans que j'ai souscrit à mon hébergement gratuit chez 1and1, 3 ans de bons et loyaux services, mais cette période est terminée.... C'est aussi pour cela que j'ai perdu mon nom de domaine en .info....&#160; </p><p>Donc le site change d'adresse, et deviens <a href="../../../../">http://fantomas.willbreak.it</a>, mettez à jours vos bookmarks :)</p> <p>Je décide donc de migrer chez un autre hébergeur, celui même qui me permet d'héberger mes projets en Python, <a href="http://upasika.fr" title="Upasika.fr">Upasika</a> et je me dis que dans la foulée pourquoi ne pas changer de solution de blogging, étant donné que Wordpress demande pas mal d'entretiens, de customisation, et deviens peu à peu une machine à gaz, alors que j'utilise que certaines fonctionnalités la majorité du temps....</p> <p>J'ai donc décidé de changer le design en passant et d'utiliser mon moteur de publication appelé <strong>Zinnia </strong>pour assurer la transition.</p> <p>Pour conservé les anciennes données, j'ai écrit une moulinette Django me servant à migrer de Wordpress vers Zinnia, et écrit en parallèle un tutorial (<em>qu'il me reste à publier</em>) expliquant la manipulation.</p> <p>En espérant que cela vous plaira !</p> fantomas42@gmail.com (fantomas)Sun, 16 Nov 2008 22:53:55 +0000https://blog.fantomas.site/blog/2008/11/16/changement-adresse-migration-django/DéveloppementExpériencesWordPress Powered https://blog.fantomas.site/blog/2007/03/28/wordpress-powered/ <p>Je viens enfin d'installer un blog digne de ce nom.</p><p>J'ai longtemps hésité entre <a href="http://www.dotclear.net/" title="DotClear">DotClear </a>et <a href="http://www.wordpress-fr.net/" title="WordPress-Fr">WordPress</a>, c'est finalement la richesse des thèmes et les fonctions Ajax qui m'auront séduit. </p><p>Mais bon, un revirement est toujours possible...</p> fantomas42@gmail.com (fantomas)Wed, 28 Mar 2007 19:08:46 +0000https://blog.fantomas.site/blog/2007/03/28/wordpress-powered/Découvertes