Fantomas' side - Articles pour le tag développementhttps://blog.fantomas.site/blog/tags/d%C3%A9veloppement/Les derniers articles taggés sous développementfrCopyright (c) 2005-2018, Julien FacheMon, 13 Feb 2017 14:04:24 +0000Action, réaction ! https://blog.fantomas.site/blog/2016/11/26/action-reaction/ <p>Récemment, j'ai eu envie de faire une <a href="https://fr.wikipedia.org/wiki/Application_web_monopage" title="SPA"><em>Application web monopage</em></a>, servant à organiser les tâches que j'ai à faire et à noter mes différentes idées pour les réaliser le moment venu. Pourquoi monopage ? Car habituellement, j'utilise juste différents fichiers textes, ce qui permet d'aller très vite dans la saisie et l'organisation des lignes, donc je voulais absolument retrouver ce côté "<em>réactif</em>".</p><p><img src="https://fantomas.site/media/uploads/todos.gif" alt="Todos" width="100%" /></p><p>Forcément, ceci nécessite pas mal de <a href="https://fr.wikipedia.org/wiki/JavaScript">JavaScript</a>, qui est le langage pour dynamiser les pages HTML. Or, même si je connais pas mal l'<a href="https://fr.wikipedia.org/wiki/ECMAScript">ECMAScript</a>, j'ai de profonds a priori sur ce langage, parfois sans fondement, je l’avoue. J'en fais à minimum, me contenant bien souvent d'utiliser <a href="https://jquery.com/">JQuery</a> pour un show/hide, un call Ajax, profiter d'un plugin et c'est tout.</p><p>J'ai testé il y a plusieurs mois <a href="https://angularjs.org/">AngularJS</a>, et même si j'ai constaté que l'industrie du JS s'est énormément développée et professionnalisée, surtout depuis l'arrivée de <a href="https://nodejs.org/">Node.js</a>, je n'ai pas réussi à adhérer aux concepts, ni même à finir le tutoriel. Bref, je partais de loin pour mon petit projet...</p><p>Mais j'ai découvert <a href="https://facebook.github.io/react/">React</a> (<em>développé par Facebook pour la petite histoire</em>), et tout a changé.</p><p>Rapidement, j'ai pu voir comment construire mon projet, tout en respectant les concepts liés à React et avoir quelque chose de fonctionnel en 2 jours. Plutôt pas mal, pour un réfractaire.</p><p>Je pense que si j'ai pu réussir à faire ce que j'avais en tête aussi vite, c'est grâce principalement à la logique de Composants, extensibles, réutilisables et embarquables, le tout géré par la syntaxe <a href="https://facebook.github.io/react/docs/jsx-in-depth.html">JSX</a> pour le rendu des templates en HTML.</p><p>Durant la réalisation de l'application, j'ai aussi vu et bénéficié des API ajoutées aux navigateurs, ce qui rend la vie tellement plus facile, d'ailleurs je pense que je n'aurais dorénavant plus besoin de JQuery de toute ma vie. :)</p><p>Parmi les choses utiles que j'ai découvertes et utilisées, je pourrais citer entre autres :</p><ul><li>Fetch</li><li>document.querySelector</li><li>L'API FormData</li><li>L'API Headers</li><li>L'API localStorage</li></ul><p>Avec tous ces éléments, je comprends qu'il soit de plus en plus tentant de remplacer des clients lourds par de réelles applications embarquées dans un navigateur.</p><p>J'ai aussi testé les nouveautés de syntaxe, comme les importations de librairies externes (le tout via <a href="https://www.npmjs.com/">NPM</a>) et les fonctions fléchées, tellement utiles. </p><p>Ceci n'étant possible qu'en utilisant un <a href="https://fr.wikipedia.org/wiki/Compilateur_source_%C3%A0_source">transpileur</a>, mais avec des outils comme <a href="http://gulpjs.com/">Gulp</a>, <a href="http://browserify.org/">Browsersify</a>, voir tout simplement <a href="https://webpack.github.io/">webpack</a>, des chaînes de constructions complexes peuvent être mises en place facilement et s'intégrer dans n'importe quel flux de développement ou de déploiement.</p><p>Bref, sans parler de React en lui-même, qui mériterait un article dédié, je suis désormais quasi reconquis par JavaScript, après disons bien 17 ans de regards en biais. </p><p>Parfois, l'accumulation des qualités compense certains défauts.</p> fantomas42@gmail.com (fantomas)Sat, 26 Nov 2016 18:52:01 +0000https://blog.fantomas.site/blog/2016/11/26/action-reaction/DécouvertesDéveloppementExpériences♪ Je lui dirais des mots vides ♫ https://blog.fantomas.site/blog/2015/02/05/je-lui-dirais-des-mots-vides/ <img src="/media/cache/02/af/02afe4f9bbf2c06821b20cb9cda6809b.jpg" alt="♪ Je lui dirais des mots vides ♫" /> <p>Depuis des temps reculés, j'essaye en composant avec mon temps et mon inspiration de toujours développer et maintenir <a href="/blog/tags/zinnia/">Zinnia</a>. Or un des points que j'essaye d'améliorer ces derniers temps, tant au niveau des résultats, que des performances, c'est la comparaison du contenu des articles, afin de retrouver les articles les plus similaires entre eux.</p><p>Une des étapes pour comparer le contenu entre les articles, va être de soustraire dans le texte l'ensemble des <a href="http://fr.wikipedia.org/wiki/Mot_vide">mots vides</a> de sens (<em>ou stop words en anglais</em>), tel que "<em>le, la, les</em>", afin de limiter le nombre de mots à comparer, tout en travaillant sur des mots dirons-nous "<em>qualifié</em>s".&#160;</p><p>Prenons un exemple concret en français :</p><blockquote><p>Maître Corbeau sur un arbre perché,<br /> Tenait en son bec un fromage.<br /> Maître Renard par l’odeur alléché<br /> Lui tint à peu près ce langage :<br /> Et bonjour, Monsieur du Corbeau.</p></blockquote><p>Une fois soustrait de ses mots vides, cet extrait de fable donnera :</p><blockquote><p>Maître Corbeau XXX XX arbre perché,<br />Tenait XX XXX bec XX fromage.<br />Maître Renard XXX X’odeur alléché<br />XXX tint X XXX XXXX XX langage :<br />XX bonjour, Monsieur XX Corbeau.</p></blockquote><p>On voit donc que l'on conserve les mots essentiels du texte, même si l'on perd le sens des phrases. Et on comprend aussi l'intérêt d'améliorer ce processus, qui peut fortement jouer sur la qualité des résultats et des performances.</p><p>Revenons à Zinnia, j'essaye donc d'améliorer cette étape du filtrage, car actuellement seuls les mots vides anglais sont pris en compte par défaut, chose peu pratique pour un blog écrit autrement qu'en langue de Shakespear.&#160; </p><p>En faisant un petit tour du Web, je constate qu'il existe bien des collections de mots vides dans différentes langues, le tout parfois même accessible en Python !</p><p>Mais les API fournies sont un peu trop optimiste, simpliste et/ou ne supportent pas Python3... De plus les collections de mots vides fournis sont parfois légères et disparates.&#160;</p><p>C'est pourquoi je me suis lancé dans <a href="https://github.com/Fantomas42/mots-vides">mots-vides</a>, une librairie Python dont les objectifs sont triples :</p><ol><li>Faciliter la maintenance des collections de mots vides.</li><li>Fournir des collections de mots clefs les plus extensives possible.</li><li>Fournir 2 APIs pour les développeurs, une bas niveau et une beaucoup plus élevée.</li></ol><p>Petit exemple de l'API haut niveau, pour récupérer et soustraire des mots vides dans un texte en français, comme dans notre précèdent exemple :</p><pre>from mots_vides import stop_words french_stop_words = stop_words('fr') print french_stop_words.rebase('Le lion est mort ce soir.') 'XX lion XXX mort XX soir.'<br />print french_stop_words.rebase('Le lion est mort ce soir.', '').split()<br />['lion', 'mort', 'soir.']</pre><p>L'API de plus bas niveau peut permettre de gérer des collections de mots vides personnalisées. Prenons par exemple que nous voulons créer une collection de langages exotiques tirés de la science-fiction, en commençant par le <a href="http://fr.wikipedia.org/wiki/Klingon_%28langue%29">Klingon</a> :</p><pre>from mots_vides import StopWord from mots_vides import StopWordFactory klingon_stop_words = StopWord('klingon') klingon_stop_words += ["HIja'", "ghobe'", 'naDev', 'nuq'] factory = StopWordFactory('mes/collections/de/mots/vides') filename = factory.get_collection_filename(klingon_stop_words.language) factory.write_collection(filename, klingon_stop_words) <br /># La collection est enregistrée # Plus tard je peux récupérer mes mots vides klingon factory = StopWordFactory('mes/collections/de/mots/vides') klingon_stop_words = factory.get_stop_words('klingon')</pre><p>L'API de bas niveau m'a surtout permis de construire les outils nécessaires à la compilation des différentes collections glanées çà et là sur le net. Grâce à ces outils, la librairie supporte <a href="https://github.com/Fantomas42/mots-vides/tree/develop/mots_vides/datas">39 langues</a> différentes, et la mise à jour ou l'ajout de langues peut se faire rapidement.</p><p>Le support de toutes ces langues est un bon début, et va donc me permettre d'améliorer ce <em>léger</em> détail qu'est le filtrage des mots vides dans Zinnia. Bien sûr d'autres utilisations sont envisageables. :)</p><p>Pour contribuer : <a href="https://github.com/Fantomas42/mots-vides">https://github.com/Fantomas42/mots-vides</a></p> fantomas42@gmail.com (fantomas)Thu, 05 Feb 2015 21:33:29 +0000https://blog.fantomas.site/blog/2015/02/05/je-lui-dirais-des-mots-vides/DéveloppementLe temps des releases : django-livereload https://blog.fantomas.site/blog/2014/06/16/le-temps-des-releases-django-livereload/ <img src="/media/cache/0a/47/0a47ce85df248b42aa4ed6d8646b361d.jpg" alt="Le temps des releases : django-livereload" /> <p>Lors de la refonte du site, j'ai découvert l'utilisation de <a title="Gulp" href="http://gulpjs.com/">Gulp</a> et de <a href="http://livereload.com/">LiveReload</a>, qui permettent de se passer de rafraîchir constamment son navigateur lorsqu'on intègre du HTML, CSS ou JavaScript. En effet lorsque une modification est enregistrée sur ces types de fichiers, le navigateur reçoit un signal lui indiquant de recharger soit la ressource, soit l'intégralité de la page.</p><p>Pas mal, mais pas encore assez satisfaisant pour moi, car j'édite aussi principalement des fichiers Python lorsque je développe sous Django, et j'aurais aimé aussi profiter du rechargement automatique du navigateur lorsque que j'édite du code. Malheureusement ce n'était pas aussi simple que cela...</p><p>Sous Django avec le serveur développement, les fichiers Python du projet sont déjà surveillés, et dès qu'une modification est détectée sur ces fichiers, le serveur redémarre pour prendre en compte la modification.</p><p>Initiative louable, mais qui complique grandement la tâche, car si je surveille aussi ces fichiers avec Gulp, le signal de rechargement sera émit et reçu par le navigateur avant que le serveur de développement Django ne soit totalement rechargé et prêt. Résultat, le navigateur n'arrive pas à recharger, je me retrouve avec une page vide et cela devient contre-productif.</p><p>Ce problème à priori peut être résolu au niveau du serveur de développement Django en utilisant des sockets persistantes et à l'heure où j'écris ces lignes un patch est dans l'attente d'intégration : <a href="https://code.djangoproject.com/ticket/18855">https://code.djangoproject.com/ticket/18855</a></p><p>C'est pour toutes ces raisons que j'ai créé et publié <a href="https://pypi.python.org/pypi/django-livereload">django-livereload</a>. Grâce à cette application qui modifie le serveur de développement, vous pouvez désormais profiter du rechargement automatique de la page en cours quand vos fichiers Python sont modifiés.</p><p>Comment ca marche ? Rappelez-vous, le serveur de développement se recharge déjà quand un fichier Python est modifié, et bien quand le serveur est totalement rechargé, une requête de rechargement est émis vers le serveur LiveReload qui lui se chargera de dispatcher la requête vers le navigateur. </p><p>En effet après quelques recherches, j'ai compris que les logiciels comme <a href="http://gulpjs.com/">Gulp</a> ou <a href="http://gruntjs.com/">Grunt</a>, se basaient sur le projet <a href="https://github.com/mklabs/tiny-lr">tiny-lr</a> lorsqu'il fallait utiliser un serveur LiveReload, hors tiny-lr fournis une API en HTTP pour pouvoir contrôler le rechargement des fichiers. Ce qui dans notre cas est l'idéal.</p><p>Pour contribuer, voici l'adresse du projet : <a href="https://github.com/Fantomas42/django-livereload">https://github.com/Fantomas42/django-livereload</a></p> fantomas42@gmail.com (fantomas)Mon, 16 Jun 2014 12:47:53 +0000https://blog.fantomas.site/blog/2014/06/16/le-temps-des-releases-django-livereload/DéveloppementExpériencesMise à jour 2014 du blog https://blog.fantomas.site/blog/2014/04/23/mise-jour-du-blog/ <p>On dit souvent que les cordonniers sont les plus mal chaussés, et en tant que développeur web je confirme l'adage. Ce blog est à l'abandon, depuis pas mal de temps déjà...</p><p>J'ai donc décidé pour remettre le pied à l'étrier, dans un premier temps de le rafraîchir visuellement et de mettre à jours ses composants, afin pourquoi pas le ressusciter dans un second temps.</p><p>Concernant la partie visuelle, j'ai cédé à la mode du design épuré, et ce pour plusieurs raisons. </p><p>L'idée originale étant de mettre en avant le contenu et sa lisibilité, ce genre de thème est adapté en utilisant de bonnes typographies. De plus en me limitant esthétiquement j'ai pu faire quelque chose de maintenable et maîtrisable à mon échelle et intégrer facilement un coté responsive au site qui lui faisait défaut en 2014.</p><p>Lors de cette refonte, je me suis aussi imposé des objectifs chiffrés en terme de temps, histoire de ne pas m'égarer sur des détails et d'avancer rapidement, d'où aussi la simplification esthétique. Cela permet de ne se concentrer que sur le cœur du site, c'est à dire les articles et leur contenu.</p><p>Pour réaliser et intégrer le design j'ai procédé en deux étapes, en réalisant d'abord une charte graphique qui me convenait, puis une fois le rendu satisfaisant à mon goût, j'ai commencé à l'intégrer dans mon système de templates. </p><p>En évitant de mélanger le fond et la forme, c'est à dire d'intégrer le HTML et le CSS en même temps qu'ils soient conçu, j'ai eu l'impression de gagner beaucoup de temps en évitant des errements et des allers-retours inutiles.</p><p>Concernant la partie intégration afin de gagner aussi du temps, j'ai utilisé un combo <a title="Gulp JS" href="http://gulpjs.com/">Gulp</a>, <a title="Sass" href="http://sass-lang.com/">Sass</a>&#160;et <a title="LiveReload" href="http://livereload.com/">Livereload</a>. Dès que je modifie les fichiers Sass, ils sont automatiquement compilés en CSS et dès qu'une modification a lieu dans le CSS ou le HTML, mon navigateur va se rafraîchir automatiquement afin de me la montrer instantanément. Fini l'époque du <em>Ctrl+F5</em> toutes les 15 secondes. :)</p><p>Pour la partie backend, j'ai opéré un nettoyage drastique sur les fonctionnalités inutiles ou presque du site afin d’accélérer au maximum le développement. Je suis resté sur <a title="Django" href="https://www.djangoproject.com/">Django</a>&#160;en utilisant la dernière mouture de <a title="Zinnia" href="http://django-blog-zinnia.com/">Zinnia</a>, mon moteur personnel de blog. La principale différence par rapport à la précédente version du site, vient du fait que les commentaires sont désormais chargés de manière asynchrone en Javascript via <a title="Disqus" href="https://disqus.com/">Disqus</a>. </p><p>Le fait de différer le chargement des commentaires, m'a permis de mettre en cache statique toutes les pages du site, afin de les servir plus rapidement, chose que je ne pouvais faire avant à cause du formulaire de commentaire et la protection <a title="Cross Site Request Forgery" href="http://fr.wikipedia.org/wiki/Cross-Site_Request_Forgery">CSRF</a>.</p><p>Pour finir sur les innovations, en termes de processus, j'ai utilisé la méthode <a title="GIT-flow" href="http://nvie.com/posts/a-successful-git-branching-model/">git-flow</a>, afin de limiter chaque phases de développement dans une branche et de pouvoir déployer le code en production sur une version stable et spécifique. Les outils et le flow proposé par git-flow rendent le processus de développement et de versionning beaucoup plus facile et professionnel, peu importe au final la taille du projet.</p><p>Pour conclure cet article, je dirais que pas mal de chemin a été parcouru depuis le début de ce blog, sous Wordpress, tant sur les domaines de ses aspirations éditoriales et esthétiques que sur le domaine technique. </p><p>Lors du passage à Django, qui m'a mené au développement de Zinnia, je voulais plus de maîtrise sur le code déployé afin de faire des choses plus complexes. </p><p>Maintenant que j'ai fait pleins de choses complexes et plus ou moins utiles, je veux plus de simplicité afin de me concentrer sur l'essentiel. </p><p>Si je dois tirer une certaine fierté de cette refonte, elle viendrait du fait que j'ai réussi à transmettre cet esprit d'essentialité et de simplicité à tous les composants du site, technique ou non.</p> fantomas42@gmail.com (fantomas)Wed, 23 Apr 2014 13:22:09 +0000https://blog.fantomas.site/blog/2014/04/23/mise-jour-du-blog/DéveloppementExpériencesLa face cachée du Sudoku https://blog.fantomas.site/blog/2011/10/11/la-face-cachee-du-sudoku/ <img src="/media/cache/6f/85/6f85967bc7fc45ed3dc82e56fa667bd7.jpg" alt="La face cachée du Sudoku" /> <h1>Introduction</h1><p>Tout commence un soir entre amis, où une envie démente de coder un petit projet nous surprend entre 2 bières. :D</p><p>Lui vient du monde Java, moi du Python, mais ayant subi la même formation, le moment fût propice pour comparer nos progrès et évolutions et aussi lancer un troll ou deux.</p><p>Ensuite nous vient l'idée de programmer un résolveur universel de <a title="Le Sudoku sur Wikipedia" href="http://fr.wikipedia.org/wiki/Sudoku">Sudoku</a>, ayant quelques connaissances de base à propos de ce jeu, j'imagine dans les grandes lignes un algorithme pour résoudre ce genre de puzzles...</p><p>L'idée générale du programme est d'appliquer de manière séquentielle les 2 ou 3 stratégies de résolutions que j'utilise moi même quand je fais un Sudoku tiré d'un magazine...</p><h1>Passage à l'acte</h1><p>Rapidement j'obtiens un résultat, mais se pose le problème de la difficulté. En effet, les grilles disponibles dans les magazines sont classées par difficulté croissante, or <a title="Classification des grilles de Sudoku" href="http://www.le-sudoku.fr/le-sudoku/classification">cette difficulté est toute relative</a>.</p><p>En effet seul le nombre de <a title="Les différentes techniques du Sudoku" href="http://www.mots-croises.ch/Manuels/Sudoku/technique.htm">techniques de résolutions</a> nécessaires (en général 3 ou 4) à un puzzle conditionne le niveau de difficulté. A savoir qu'il existe de techniques très complexes pour résoudre certaines grilles de Sudoku, mais il ne sera jamais nécessaire même à un niveau dit "<em>Diabolique</em>" de les maîtriser. Seules les techniques élémentaires seront nécessaire pour 95% des grilles publiées.</p><p>Mais concernant les 5% restant, là cela devient beaucoup plus complexe, car après plusieurs heures de recherches et de compréhension de ces techniques, je décide d'en implémenter certaines dans le résolveur pour augmenter ses chances de résolution. </p><p>Mais le problème reste entier, même si j'augmente le nombre d'algorithmes de résolution, si je tombe sur un cas que je n'ai pas prévu, je ne peux pas résoudre complètement la grille. En effet, le programme n'est pas capable d'improviser une solution ou d'échafauder une hypothèse qui lui permettrait de se sortir de ce cas imprévu.</p><p>A la suite de cette série d'échecs, je décide d'implémenter un algorithme de résolution basé sur le <a title="BackTracking sur Wikipedia" href="http://fr.wikipedia.org/wiki/Retour_sur_trace">backtracking</a>, solution qui me convient beaucoup mieux car le taux de résolution des puzzles est de 100%, mais insatisfaisante car elle ne permet pas d'expliquer la solution et le temps de résolution d'un puzzle est peu prédicable et très fluctuant.</p><h1>Réflexions</h1><p>En guise de conclusion à cette immersion dans le monde du Sudoku qui s'est révélée au final bien plus riche qu'il ne le semblait aux premiers abords, j'ai appris une belle leçon en matière de programmation et surtout d'algorithmique. </p><p>En effet mimer la façon de penser d'un homme pour résoudre certains problèmes de programmation peut parfois se révéler intéressant et source de solutions, mais il ne faut pas oublier que l'on traite avec une machine. <br />Une machine n'a pas la capacité d'innovation ou d'évolution face à un problème non identifié, par contre elle est capable de retenir des millions d'informations et de les traiter beaucoup plus rapidement que n'importe quel humain et ça, c'est un avantage indéniable.</p><p>Même si un humain peut utiliser la technique du <em>Backtracking</em> (appelé aussi <a title="Nishio et Sudoku" href="http://www.mots-croises.ch/Manuels/Sudoku/Nishio.htm">Nishio</a>) pour résoudre sa grille, il mettra un temps phénoménal mais il n'y arrivera que s'il est très rigoureux et ce n'est pas du tout ludique.</p><p>Par contre pour une machine, la donne s'inverse, la machine est rigoureusement rigoureuse et peut faire tous ces calculs très rapidement.</p><p>Pour conclure, même si un humain et une machine peuvent plus ou moins faire la même chose, il ne faut jamais oublier de prendre en compte les points forts et points faibles de l'un et de l'autre dans la conception d'un algorithme.</p><h1>Résultats</h1><p>Le résultat de toute ces expériences est disponible sur PyPI sous le nom de <a title="Mon solveur de sudoku sur PyPI" href="http://pypi.python.org/pypi/sudoku-solver">sudoku-solver</a>.</p><pre>$ easy_install sudoku-solver $ sudoku_solver votre_grille.txt</pre><p>Vous pouvez éventuellement contribuer sur la page Github du projet à l'adresse suivante : <a title="Sudoku Solver sur Github" href="https://github.com/Fantomas42/sudoku-solver">https://github.com/Fantomas42/sudoku-solver</a></p><p>Et pour terminer, je n'ai pas pu m'empêcher de réaliser une démo web de ma librairie sous le framework Django. Donc si vous voulez résoudre ou vérifier vos grilles de Sudoku, allez à cette adresse : <a title="Résolvez vos puzzles de Sudoku en ligne" href="http://sudoku.willbreak.it/">http://sudoku.willbreak.it/</a></p><p>Bon puzzles !</p> fantomas42@gmail.com (fantomas)Tue, 11 Oct 2011 16:49:56 +0000https://blog.fantomas.site/blog/2011/10/11/la-face-cachee-du-sudoku/DécouvertesDéveloppementExpériencesÔ middleware, mon beau middleware : Request Template Loader https://blog.fantomas.site/blog/2011/03/08/o-middleware-mon-beau-middleware-request-template-loader/ <img src="/media/cache/74/59/74593d216dc7558383bf9189981a97cf.jpg" alt="Ô middleware, mon beau middleware : Request Template Loader" /> <p>Dans le monde du web, là où tout est anarchie (ou presque), je me retrouve confronté assez souvent à cette problématique : </p><blockquote><p>Comment afficher le contenu d'un site réalisé avec Django sur un autre site déjà existant ?</p></blockquote><p>Là où je bosse, on aime bien les <a title="Les balises IFRAME" href="http://www.w3.org/TR/html4/present/frames.html#h-16.5">iframes HTML</a> (no comments please :)), mais le contenu ou le style de la frame incluse ne correspondent pas forcément au site recevant la frame. L'idée, vu qu'on se trouve à la base dans un environnement <a title="Le projet Django" href="http://www.djangoproject.com/">Django</a>, serait de déployer un nouveau site, avec son propre jeu de templates prévues pour le site incluant les frames.</p><p>Mais ce genre de technique nécessite de mettre en place un nouveau domaine, de déployer et de maintenir 2 sites. Bon vous me direz que ce n'est pas forcément ce qu'il y a de plus dur, mais il y a moyen de faire mieux. Et surtout que ce passe-t-il si vous devez faire ce genre d'opération non pas sur 1 site, mais sur plusieurs. Tout de suite cela devient plus ennuyeux. :(</p><p>C'est là où intervient la solution du <a title="Les middlewares sous Django" href="http://docs.djangoproject.com/en/dev/topics/http/middleware/">middleware</a>. L'idée est de pouvoir passer en GET un paramètre qui conditionnera le chargement des templates dans le site source. Comme cela peu importe combien de frames au look différent on devra gérer, la mise en forme et la personnalisation du contenu se fera très facilement.</p><p>Maintenant place au code, les explications sur le fonctionnement viennent directement après.</p><pre>import os from urllib import urlencode from urlparse import urlparse from urlparse import urlunparse try: # For Python &lt; 2.6 from urlparse import parse_qs except ImportError: from cgi import parse_qs from django.conf import settings from django.utils.encoding import smart_str from BeautifulSoup import BeautifulSoup GET_VAR_NAME = getattr(settings, 'TEMPLATE_GET_VAR_NAME', 'from_source') class RequestTemplateMiddleware(object): """Middleware to modify on the fly the loading of the templates""" def __init__(self): self.original_template_dirs = settings.TEMPLATE_DIRS def process_request(self, request): source = request.GET.get(GET_VAR_NAME) if source: settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'templates', source),) + \ settings.TEMPLATE_DIRS return None def process_response(self, request, response): settings.TEMPLATE_DIRS = self.original_template_dirs source = request.GET.get(GET_VAR_NAME) if source and '&lt;html' in response.content: soup = BeautifulSoup(smart_str(response.content)) for link in soup.findAll('a'): link['href'] = self.update_link(link['href'], source) for form in soup.findAll('form'): form['action'] = self.update_link(form['action'], source) form.insert(0, '&lt;div&gt;&lt;input type="hidden" name="%s" ' \ 'value="%s" /&gt;&lt;/div&gt;' % (GET_VAR_NAME, source)) response.content = str(soup) return response def update_link(self, link, source): """Update the links with the good GET parameter""" url_parts = urlparse(link) query_dict = parse_qs(url_parts.query) query_dict.update({GET_VAR_NAME: source}) return urlunparse((url_parts.scheme, url_parts.netloc, url_parts.path, url_parts.params, urlencode(query_dict), url_parts.fragment))</pre><p>Comme on peut le voir, ce middleware va court-circuiter l'ordre de chargement des templates en modifiant la variable <strong>TEMPLATE_DIRS</strong> utilisée par <a title="Chargement des templates sous Django" href="http://docs.djangoproject.com/en/1.2/ref/templates/api/#loader-types">django.template.loaders.filesystem.Loader</a>, grâce à la variable <strong>from_source</strong> passée dans l'url en GET. </p><p>Ensuite il ne reste plus qu'à créer le dossier de templates correspondant à la variable <strong>from_source</strong> et d'y placer les templates personnalisés. A savoir que le nom de la variable passée en GET est configurable pour plus de souplesse. </p><p>La seule dépendance requise est <a title="Documentation de BeautifulSoup" href="http://www.crummy.com/software/BeautifulSoup/documentation.html">BeautifulSoup</a> qui va modifier le contenu HTML afin de pouvoir continuer à utiliser le middleware quand on clique sur un lien ou on valide un formulaire.</p><p>Au delà de l'utilité de ce bout de code, j'espère que cela va vous motiver à programmer et utiliser vos propres middlewares, car cela s'avère souvent la meilleure solution à un problème complexe lors du développement d'un site internet avec Django.</p> fantomas42@gmail.com (fantomas)Tue, 08 Mar 2011 14:38:28 +0000https://blog.fantomas.site/blog/2011/03/08/o-middleware-mon-beau-middleware-request-template-loader/DéveloppementExpériencesLe temps des releases : easy_extract https://blog.fantomas.site/blog/2010/01/19/le-temps-des-releases-easy-extract/ <img src="/media/cache/9a/c2/9ac2da5d13ce19a88cda6c86704d1127.jpg" alt="Le temps des releases : easy_extract" /> <p>Imaginons que j'ai sur un serveur de donnée une grosse quantité d'archives sous différents formats, tel que RAR, ZIP, XTM... </p><p>Si je souhaite extraire toutes ces archives, je devrais aller trouver chaque archives dans son répertoire, taper la bonne commande pour pouvoir les extraire, les réparer au besoin et ainsi de suite... Plutôt fastidieux non ? :(</p><p>Sur ce constat m'est venu l'idée de <strong>easy_extract</strong>, un script écrit en Python qui va analyser récursivement les répertoires à la recherche d'archives ou de collections d'archives pour les extraire et les réparer automatiquement si elles sont corrompues.</p><p>Pour cela, il suffit de lancer le script de la manière suivante par exemple :</p><pre>$ easy_extract -r mes_archives/</pre><p>Pratique et le gain de temps est évident, car une fois le script lancé, vous n'avez plus à vérifier que l'extraction s'est bien déroulée pour ensuite passer à la suivante, donc a scotcher devant votre terminal. Victoire une tâche fastidieuse de plus automatisée. :D</p><p>Pour l'installation, il est nécessaire d'installer les paquets suivant avant :</p><ul><li>par2</li><li>unrar-free</li><li>7zip-full</li></ul><p>Ensuite l'installation du script se fait grâce à easy_install :</p><pre>$ easy_install easy_extract</pre><p>Bien sûr le code est open-source, donc si vous voulez contribuer, forker ou juste critiquer, le code se trouve à l'adresse suivante : <a title="Source de easy_extract" href="http://github.com/Fantomas42/easy-extract">http://github.com/Fantomas42/easy-extract</a></p><p>Bonne décompression et bon leech.</p> fantomas42@gmail.com (fantomas)Tue, 19 Jan 2010 10:47:56 +0000https://blog.fantomas.site/blog/2010/01/19/le-temps-des-releases-easy-extract/DéveloppementLe temps des releases : Vélib'erator https://blog.fantomas.site/blog/2009/09/24/le-temps-des-releases-veliberator/ <img src="/media/cache/62/ea/62ea6a9ad14f0fac4c578fa52f8b552b.jpg" alt="Le temps des releases : Vélib&#39;erator" /> <p>Suite à mon abonnement à <a title="Vélib" href="http://velib.paris.fr/">Vélib'</a>, habitant près d'une station récemment construite, j'ai vite remarqué que de trouver un vélo en bon état ou une place de parking à proximité avant les 30 minutes fatidiques et payantes pouvait vite devenir un calvaire.</p><p>Sur ce, après quelques recherches,&#160; j'ai pu constater que les informations sur l'état des stations du réseau Vélib' étaient librement accessibles. D'où l'idée de créer un paquet python nommé <a title="Sources du paquet python Veliberator" href="http://pypi.python.org/pypi/veliberator/">Veliberator</a>, me permettant depuis mon shell de consulter l'état de mes stations favorites.</p><p>Pour les fans de la ligne de commande, essayez ceci :</p><pre>$ sudo easy_install veliberator $ sudo synchronize.py $ find_place.py 42008</pre><p>Partant de là, je me dis qu'il serait dommage de m'arrêter à ce stade du développement, d'autant plus que mon problème pour trouver une place libre rapidement ne se résous que depuis mon ordinateur, il faudrait donc que ce service soit accessible partout et pour tout le monde.</p><p>Un site web semble être la solution idéale, d'autant plus si on est capable d'optimiser l'affichage des pages au type de support, par exemple un mobile.</p><p>Equipé de mon module python et de Django, j'ai donc réalisé le site <a title="Vélib'erator la libération des stations Vélib'." href="http://veliberator.com">http://veliberator.com</a>.</p><p>Au programme du site :</p><ul><li>Consultation des <a title="Station Vélib' 42008" href="http://veliberator.com/42008">statuts des stations Vélib'</a>.</li><li>Affichage des stations aux alentours.</li><li>Affichage des <a title="Stations Vélib près de la Tour Eiffel." href="http://veliberator.com/lieux/monument/tour-eiffel/">lieux importants</a> près des stations.</li><li><a title="Flux RSS de la station 12002 et des alentours." href="http://veliberator.com/rss/around/12002">Flux RSS</a> pour monitorer le statut des stations.</li><li>Vues par <a title="Stations Vélib' de Saint Mandé" href="http://veliberator.com/ville/94160/">ville</a>, départements, statut, adresse.</li><li><a title="Statistiques du réseau Vélib'" href="http://veliberator.com/stats/">Statistiques</a> du réseau Vélib'.</li><li>Recherche par : adresse, métro, monument, code postal, coordonnées GPS.</li><li>Calcul des distances.</li><li>Traçage d'<a title="Itinéraire entre la station 42008 et 12001" href="http://veliberator.com/route/42008/12001">itinéraires</a> entre stations Vélib'.</li><li>Gestion de favoris.</li><li>Interfaces claires et unifiées.</li><li>Cartes détaillées et en <a title="Vue plein écran !" href="http://maps.veliberator.com/13053/">plein écran</a>.</li><li>Géo-localisation automatique.</li><li>Internationalisation </li><li>Support pour les téléphones <a title="Vélib'erator version iPhone et mobile." href="http://m.veliberator.com">mobiles et iPhone</a>.</li><li>Support pour les Télésites Freebox.</li></ul><p>En effet le site tourne sous plusieurs versions, chacune adaptées à son environnement d'affichage, et à tout moment je peux consulter ces informations.</p><p>Dans mon cas, quand je rentre du travail en Vélib' et qu'il n'y a plus de place en bas de chez moi, je sais directement où aller pour trouver une place libre, sur mon téléphone. Adieu les rondes au hasard à la recherche d'une place libre... Merci Vélib'erator ! :D</p><p>Si vous avez des suggestions, je suis ouvert à toutes propositions d'amélioration.</p><p><a title="Vélib'erator.com" href="http://veliberator.com">http://veliberator.com</a></p><p><a title="Vélib'erator version mobile" href="http://m.veliberator.com">http://m.veliberator.com</a></p><p><em><strong>Edit 30 septembre 2009</strong> : Suite à un email provenant de la société JCDecaux, je me vois dans l'obligation de ne plus utiliser leurs données sur les stations vélib selon les articles L. 112-3 al 2 et L.341-1 du code de la propriété intellectuelle. Données qui sont pourtant accessible publiquement... A priori, avec Vélib, il vaut mieux éviter les initiatives personnelles.</em></p> fantomas42@gmail.com (fantomas)Thu, 24 Sep 2009 14:16:23 +0000https://blog.fantomas.site/blog/2009/09/24/le-temps-des-releases-veliberator/DécouvertesDéveloppementLe temps des releases : Django-sekh https://blog.fantomas.site/blog/2009/08/31/le-temps-des-releases-django-sekh/ <img src="/media/cache/5a/0b/5a0b1dfc28bb1fa4d28b98d0d50d2208.jpg" alt="Le temps des releases : Django-sekh" /> <p>Vous avez certainement déjà vu dans <strong>Google</strong> quand vous consultez une page depuis son <strong>cache</strong>, les <strong>termes de la recherche sont coloriés</strong> dans le contenu de la page pour permettre de les discerner rapidement.</p><p>De ce principe certains sites ont adapté <strong>la même technique</strong> en coloriant certains mots de la page correspondant à la recherche de l'utilisateur si il provient d'un moteur de recherche.&#160;</p><p>C'est ce que <strong>django-S</strong>earch<strong> E</strong>ngine <strong>K</strong>eywords <strong>H</strong>ighlighter fait ! </p><p>Une fois installé avec <a title="BeautifulSoup" href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a>, il suffit juste d'ajouter ce middleware à la fin de la liste dans votre fichier <strong>settings</strong>.</p><pre>MIDDLEWARE_CLASSES = ( ... 'sekh.middleware.KeywordsHighlightingMiddleware', )</pre><p>Moi quand c'est facile à installer, j'aime ! :D</p><p>Ce middleware va rajouter une balise <strong>span</strong> autour des mots de la recherche, le tout avec des classes qui vont bien permettant la décoration en CSS.</p><p>L'inconvénient est que si votre HTML est mal formatté, le middleware risque de faire planter la page.</p><p>Pour voir <a title="Exemple de django-sekh" href="http://fantomas.willbreak.it/blog/2009/jul/19/release-django-smileys/?hl=django%20middleware">un exemple cliquez ici</a>.</p><p>Pour plus d'informations et pour télécharger le code : </p><p><a title="django-sekh" href="http://github.com/Fantomas42/django-sekh/tree/master">http://github.com/Fantomas42/django-sekh/tree/master</a></p> fantomas42@gmail.com (fantomas)Mon, 31 Aug 2009 18:17:51 +0000https://blog.fantomas.site/blog/2009/08/31/le-temps-des-releases-django-sekh/DéveloppementLe temps des releases : Django-smileys https://blog.fantomas.site/blog/2009/07/19/release-django-smileys/ <p>Parfois il est temps de se sortir les doigts du code, et d'en parler !<br />Mais pour en parler, il faut documenter, ce qui prend un peu de temps, mais j'y travaille.</p><p>Pour commencer je vais vous présenter une de mes applications favorites, par sa simplicité et son utilité incroyable. :D</p><p><strong>Django-smileys</strong> est une application <strong>Django</strong> comme son nom l'indique, permettant d'inclure facilement dans ses templates des smileys, de ce genre :) :p.</p><p>Pour cela, une fois l'application téléchargée et installée dans votre projet django, il vous suffit dans vos templates d'utiliser le filtre qui va convertir tout les code smileys définis dans SMILEYS_LIST.</p><pre>{% load smiley_tags %} {{ object.content|smileys }}</pre><p>Plutôt facile non ? Surtout que l'on peut maintenant convertir tout type de contenu texte.</p><p>La liste des smileys est configurable, ainsi que l'url de dépot et la classe d'habillage CSS.</p><p>Pour télécharger ce projet hallucinant : <a title="Dépot de Django-smileys" href="http://github.com/Fantomas42/django-smileys/tree/master">http://github.com/Fantomas42/django-smileys/tree/master</a></p><p>Bientôt d'autres releases.</p> fantomas42@gmail.com (fantomas)Sun, 19 Jul 2009 13:25:48 +0000https://blog.fantomas.site/blog/2009/07/19/release-django-smileys/DéveloppementDjango unique et timed sessions https://blog.fantomas.site/blog/2008/12/24/django-unique-et-timed-sessions/ <img src="/media/cache/7a/e7/7ae7794ebfb995588c172aa4c7bec0af.jpg" alt="Django unique et timed sessions" /> <h1>Comment rendre unique les comptes utilisateurs connectés sur un site en Django ? </h1><p>Ce genre de problématique se retrouve souvent sur les sites internet proposant des abonnements à un service en ligne, voulant empêcher le partage d'abonnement. </p><p>Pour les besoins d'un projet spécifique en Django au sein de la <a href="http://www.emencia.fr" title="Emencia">société Emencia</a> là où je travaille, j'ai du développer un moyen d'empêcher 2 utilisateurs de se connecter sur un compte utilisateur en même temps. </p><p>Mais le problème ne s'arrête pas là, comment empêcher la connection et la déconnection successive entre 2 utilisateurs ? L'idée est de donner un temps minimum de connection à chaque session ouverte pour empêcher la déconnection, par exemple 5 minutes. </p><p>Pour cela j'ai écrit un <strong>Middleware </strong>pour Django qui va se charger de rendre unique chaque sessions utilisateurs sur le site. Utiliser un middleware donne l'avantage d'être réutilisable et facile à installer. </p><pre>MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'utsessions.middleware.UTSessionMiddleware', )</pre><p> Après plusieurs refactorings et tests, permettant de configurer le comportement du middleware, comme la déconnection automatique, j'ai publier le code source sur GoogleCode pour que tout le monde puisse en profiter.</p><p>Pour plus d'informations, ou pour télécharger le code, consulter le site web du projet : <a href="http://code.google.com/p/django-ut-sessions/">Django UT Sessions</a>. </p><p>Pour installer le module depuis Pypi : </p><pre>$ easy_install utsessions</pre> fantomas42@gmail.com (fantomas)Wed, 24 Dec 2008 10:12:22 +0000https://blog.fantomas.site/blog/2008/12/24/django-unique-et-timed-sessions/DéveloppementPython 3.0 : compatibilités et évolutions https://blog.fantomas.site/blog/2008/12/11/python-30-compatibilite-evolutions/ <img src="/media/cache/4d/d1/4dd177ac01eca69c63e2165b7c4f315e.jpg" alt="Python 3.0 : compatibilités et évolutions" /> <p>C'est le 3 décembre dernier que la <a href="http://www.python.org/download/releases/3.0/">version 3.0 de Python</a> est sortie. Une version attendue par une grande partie de la communauté Python. </p><p>Au programme, un bon coup de nettoyage de la librairie standard, des nouveautés comme le passage en tout Unicode, et une nouvelle syntaxe. Même si cette dernière reste proche des moutures 2.x, elle est clairement incompatibles avec les versions précédentes. Un fait assumé par les créateurs. </p><p>Pour effectuer la transition en douceur, les versions 2.6 et 2.7 ont amorcées le travail en intégrant une partie des nouveaux concepts présent dans Python 3.0, comme la <em>Curryfication</em>, ou l'implémentation de pseudo opérateurs ternaires. </p><p>De plus le script <a href="http://svn.python.org/view/sandbox/trunk/2to3/">2to3</a> est là pour finaliser cette transition en convertissant le code écrit en 2.x vers la version 3. Il serait dommage que les anciens projets basé sur la version 2.x meurent du fait d'une trop grande difficulté de migration. </p><p>Craignant une fuite de la communauté Python, c'est sur ces sujets que nous avons été consultés par le site <strong>LeMagIT.fr</strong>, mon collègue et moi, pour expliquer notre point de vue sur cette nouvelle version dîtes mature. </p><p>L'article se situe à l'adresse suivante : <a href="http://www.lemagit.fr/article/web-developpement-communaute/1939/1/avec-version-python-mue-pour-harmoniser/">Harmonisation au sein de Python 3.0</a>.</p><p> <strong>Mise à jour</strong> : <a href="http://www.toonux.com/news/python-3k-a-lhonneur-dans-le-mag-it-les-developpeurs-demencia-nous-expliquent-les-tenants-et-les-aboutissants-de-cette-migration-necessaire" title="Toonux.com">Toonux.com relaye l'info.</a></p> fantomas42@gmail.com (fantomas)Thu, 11 Dec 2008 01:59:10 +0000https://blog.fantomas.site/blog/2008/12/11/python-30-compatibilite-evolutions/DéveloppementOgame Statistics https://blog.fantomas.site/blog/2008/03/02/ogame-statistics/ <img src="/media/cache/7a/36/7a3635d3277fc35ef96d0597c303e101.jpg" alt="Ogame Statistics" /> <p>Lors de mon dernier article, je vous ai parlé de Open Flash Chart, en vous spécifiant que cela avait un rapport avec un prochain article, cet article le voilà. </p><p><a href="http://ostat.upasika.org" title="Ogame Statistics">Ogame Statisitics</a> est un nouveau site que je viens d'ouvrir permettant de consulter les statistiques de tous les joueurs et alliances présents sur un univers de jeu de <a href="http://ogame.fr" title="Ogame.fr">Ogame</a>. </p><p>Le site réalisé grâce au framework <a href="http://www.djangoproject.com" title="Django Project">Django</a>, permet de créer une interface visuel des statistiques collectées par un module de mon robot pour Ogame, <a href="http://fantomas.willbreak.it/2008/jan/22/ogame-attack-watcher-la-suite/" title="Ogame Attack Watcher, la suite !">Obot</a> dont j'ai déjà parler précèdement sur le blog. </p><p>En effet j'ai développé un nouveau module pour mon robot permettant de récolter toute les statistiques à un moment donné sur un serveur de jeu.</p><p> Des initiatives ont déjà été prises pour effectuer des visualisations de statistiques, utiles pour les alliances, mais le gros inconvénient de ces systèmes est qu'il est nécessaire de rentrer les données manuellement et assez fréquemment pour obtenir un suivi, ce qui est une tache longue et répétitive donc idiote :) </p><p> Là où se démarque Ogame Statistics, est que la mise à jours des données est automatique et régulière, car elle est prise en charge par Obot :) </p><p> Au menu du site, on trouvera un moteur de recherche, pour permettre de retrouver son profil ou son alliance, ses dernières statistiques, ainsi que celle de son alliance, et des graphiques d'évolutions réalisés avec Open Flash Chart. Une petite touche d'Ajax avec <a href="http://www.jquery.com" title="jQuery.com">jQuery</a> pour le trie des données et le résultat n'en est que mieux. </p><p>La version 1.0 vient de sortir, mais va venir s'agrémenter de nouvelles fonctionnalités orientés sur la comparaison des différents univers de jeux, et la gestion des alliances inter-univers. </p><p>Le site : <a href="http://ostat.upasika.org" title="Ogame Statistics">Ogame Statistics </a></p> fantomas42@gmail.com (fantomas)Sun, 02 Mar 2008 19:59:32 +0000https://blog.fantomas.site/blog/2008/03/02/ogame-statistics/DéveloppementOpen Flash Chart avec le Python's style ! https://blog.fantomas.site/blog/2008/02/28/open-flash-chart-python/ <img src="/media/cache/de/06/de06759e66c72b2c17b9d268d351f8a1.jpg" alt="Open Flash Chart avec le Python&#39;s style !" /> <p>Récemment, pour les besoins d'un projet dont je parlerais bientôt lors d'un prochain article, je me suis mis à rechercher une librairie Python me permettant de réaliser rapidement de jolis graphiques statistiques. </p><p>Passé les <a href="http://home.gna.org/pychart/" title="Le site de PyChart">PyChart</a> et autre ChartDirector. Mon choix s'est porté sur <a href="http://teethgrinder.co.uk/open-flash-chart/" title="Le site d'Open Flash Chart">Open Flash Chart</a>, une librairie permettant de réaliser des graphiques statistiques grâce à Flash. </p><p>Comme son nom le laisse supposer, la librairie est <em>open source</em>, un point primordial ;) Un site bien documenté avec des exemples complets, permettant une prise en main rapide et un résultat graphique abouti, m'auront convaincu assez rapidement.</p><p> L'avantage de cette librairie est qu'il est techniquement possible de l'interfacer avec tous les langages, car le fichier flash générant le graphique, se charge de récupérer un fichier au format texte, contenant les données du document. </p><p> Il suffit donc de générer un simple fichier texte, pour pouvoir afficher un graphique complexe, ce qui est un avantage notable pour la machine qui hébergera la représentation des graphiques. En effet on nous n'avons pas générer d'image, comme les autres librairies, et encore moins à les stocker. </p><p>La bonne nouvelle, est qu'il existe déjà des APIs pour différents langages, tel PHP, Perl, mais aussi Python. Génial ! :) </p><p>La moins bonne nouvelle vient du fait, que cette dite API Python ne fonctionne pas <em>ou plus</em>, et n'est clairement pas maintenue à jours. :( </p><p>L'autre bonne nouvelle, est que j'ai pris le soin de recoder l'API Python pour Open Flash Chart. :) </p><p> En me basant sur la documentation et sur le travail de la précédente API écrite par Guenther Harrasser, j'ai corrigé, nettoyé et mis à jour le code. Pour finalement le réécrire complétement... </p><p> J'en ai profité pour mailer l'auteur, et lui proposer mon correctif. En l'attente d'une réponse, je me propose pour vous faire partager mon travail. </p><p>Nous allons dans cette exemple générer un graphique simple composé d'une ligne et d'une série de barres, la ligne étant placé sur l'axe Y de droite. </p><pre>from openflashchart import Graph # Création du graph et titrage graph = Graph() graph.title('My Graph Title', '{font-size:20px}') # Insertion des barres, de la ligne, # et des données associées graph.bar_outline(50, '#005aff', '#666666', 'Bar Stats', 10) graph.set_data(range(10)) graph.line_hollow(2, 5, '#05a0FF', 'Line Stats', 10) graph.set_data(range(10, 20)) # Assignation de la ligne sur l'axe Y de droite, # des libelles en abscisse, et des légende en ordonnée. graph.attach_to_y_right_axis(2) graph.set_x_labels(['x_%i' % i for i in range(10)]) graph.set_y_legend('Legend Left', 15, '#ff4a00') graph.set_y_right_legend('Legend Right', 15, '#4aff00') # Génération du graphique stat = graph.render()</pre><p>Télécharger <a href="http://fantomas.willbreak.it/wp-content/uploads/2008/02/open-fc.zip" title="Open Flash Chart : API Python">Open Flash Chart : API Python</a> </p><p><strong>Edition du 30 mai 2007 :</strong> Une amélioration du code de rendu HTML a été faite, pour gagner en lisibilité et aussi pour facilité la manipulation du DOM.</p> fantomas42@gmail.com (fantomas)Thu, 28 Feb 2008 22:51:47 +0000https://blog.fantomas.site/blog/2008/02/28/open-flash-chart-python/DéveloppementOgame Attack Watcher, la suite ! https://blog.fantomas.site/blog/2008/01/22/ogame-attack-watcher-la-suite/ <img src="/media/cache/1f/0e/1f0e63cdd26059036d598f5b9495aca4.jpg" alt="Ogame Attack Watcher, la suite !" /> <p>Cela fait maintenant quelques semaines que le silence se fait sur le blog, ceci est du au développement intensif de mon dernier projet, mon robot pour Ogame, j'ai nommé <strong>Obot</strong>. C'est l'occasion idéale de faire un focus sur la progression de ce projet.</p> <p>Je résume le projet dont <a href="http://fantomas.willbreak.it/blog/2007/sep/25/ogame-attack-watcher/" title="Ogame Attack Watcher">j'ai parlé dans un article précédent</a> : j'ai ouvert le site web <a href="http://oaw.upasika.org" title="oaw.upasika.org">OAW</a> pour mettre à disposition les avancées techniques du robot, et éventuellement recruter de nouveaux contributeurs pour ce projet.</p> <p>Avec actuellement en frontal un site réalisé grâce au framework python <a href="http://www.djangoproject.com" title="Le site du framework Django">Django</a>, qui m'as permis d'interfacer des fonctionnalitées de la librairie <strong>Obot</strong>, comme la vérification du compte Ogame à l'inscription, j'ai réalisé le paramétrage du robot via des interfaces en Ajax, et une internationalisation facile à mettre en place et à mettre à jours.</p> <p>J'ai déployé en arrière plan une version stabilisée par des tests unitaires et fonctionnels, une version serveur du robot, capable de gérer jusqu'à 1000 comptes en simultanés (vive la théorie :p)</p> <p>Résultat, le premier bot <strong>online gratuit</strong> pour Ogame ! <strong>Open-source</strong> en plus :D</p> <p><a href="http://oaw.upasika.org" title="Ogame Attack Watcher"><strong>http://oaw.upasika.org</strong></a></p><p>Dénommé à la base Ogame Attack Watcher, car à la base le robot et le site web étaient uniquement destinés à la surveillance des attaques sur les planètes de son compte, le développement de la librairie de fonctions contenues dans <strong>Obot</strong> a pris une tournure différente : automatiser et optimiser le développement ses planètes.</p> <p>Au programme :</p><ul><li>Alerte par e-mail en cas d'attaques ou autres événements</li><li>Édification automatique des bâtiments</li><li>Constitution automatique de la flotte</li><li>Construction automatique des défenses</li><li>Développement automatique de la recherche</li><li>Stratégie de rétablissement du niveau d'énergie</li><li>Stratégie de préservation des points en cas d'attaque ennemie</li><li>Envois par e-mail des nouveaux messages in-game</li></ul><p>Les fonctionnalités actuelles du robot permettent de délaisser son compte pendant plusieurs jours sans avoir à s'inquiéter de son développement, sans avoir à se mettre en mode vacance !</p> <p>L'API générale étant stabilisée, le développement des fonctionnalités a été plutôt rapides, chacune étant modulaires, ont peux très bien les activer à la demande par simple configuration.</p> <p>Les développements actuels concernent le site web, mais aussi dans le perfectionnement des modules de stratégie, et pour finir je vais bientôt commencer le développement du module automatisant le raid. Il est aussi necessaire de maintenir le code à jour du fait, des modifications apportées sur les pages du jeu et des règles. Pour l'instant le robot tourne jusqu'à la version <em>0.78c</em> du jeu.</p> <p>Pour une version téléchargeable, ce n'est pas pour tout de suite, n'ayant pas toutes les compétences sur le paquetage d'application python surtout sur plate-forme Windows. Je fais un appel donc aux bonnes volontés :) La distribution des sources pour les utilisateurs avancés, peux se faire par le svn, par simple demande mail.</p> fantomas42@gmail.com (fantomas)Tue, 22 Jan 2008 21:29:57 +0000https://blog.fantomas.site/blog/2008/01/22/ogame-attack-watcher-la-suite/Développement