1. Authentification avec django_hg, partie 2

    La dernière fois, nous avons vu comment servir django avec mod_wsgi.

    Une fois Apache correctement configuré, effectuer l’authentification via django a été un jeu d’enfants.

    Tout d’abord, rééditer la configuration du virtual host Apache pour ajouter cette ligne :

    WSGIPassAuthorization On
    

    On redémarre ensuite Apache.

    Cette ligne informe Apache de transmettre les informations d’authentification au programme wsgi, en l’occurence django. Sinon, par défaut, Apache ne les transmets pas [en].

    Ensuite, ajouter un decorator devant les vues que vous souhaitez protéger par l’authentification HTTP. Je me suis basé sur ce snippet [en] en l’adaptant au cas particulier de django_hg, c’est à dire que je souhaite une authentification HTTP uniquement si c’est un client Mercurial qui tente une commande clone, push ou pull.

    Et voilà, le tour est joué

    Pour détecter le cas de figure, je m’étais dans un premier temps basé sur le HTTP_USER_AGENT transmis par le client. Seulement je me suis dit que cette valeur risquait bien de changer, selon les clients ou avec le temps, même si Murky [en] par exemple, utilise le même.

    Je suis donc en train de refactoriser cette partie en me basant uniquement sur la présence de l’argument cmd dans l’url et en vérifiant la validité. Pour cela j’ai mis en place un certain de tests unitaires, pour vérifier que je ne créais pas de régression. J’ai commité le résultat hier soir sur bitbucket [en].

    Le dernier gros point complexe du programme est en passe d’être achevé. Je souhaite effectuer une dernière modification pour reproduire le comportement classique des projets open-source: clone et pull peuvent être anonymes mais pas le push, pour des raisons évidentes de sécurité et de traçabilité.

    Honnêtement, au départ, je ne pensais être en mesure d’intégrer à ce point django et Mercurial, en tout cas, certainement pas aussi facilement.

    La suite devrait être assez simple: ajouter les fonctionnalités manquante (diff, branches, etc.) et faire un outil de ticketing.

    Text
    6 months ago
  2. Authentification avec django_hg

    La semaine dernière [fr], j’ai réussi à utiliser django [en] pour répondre aux commandes de Mercurial.

    L’étape suivante dans cette logique était donc de faire l’authentification grâce à django. Le code a été poussé sur bitbucket [en] hier soir. Je n’ai par contre pas eu le temps d’écrire la documentation, j’espère pouvoir faire cela dans la journée.

    Si l’authentification est finalement contenue dans un decorator, j’ai fait pas mal d’administration pour mettre en place un environnement de développement. En effet, j’ai tout d’abord configuré Apache pour qu’il serve django. Cela n’a pas été sans mal, car la configuration de mod_wsgi m’a donné un peu de fil à retordre.

    La documentation officielle de django [en] recommande d’utiliser mod_wsgi [en]. Je me suis donc tourné vers cette solution. Malheureusement, la version distribuée par MacPort [en] est vieille (version 1.1 alors que nous en sommes à la 2.5 en stable et que la 3.0 est en RC) et surtout elle est couplée à Python2.4, alors que django utilise Python2.5. J’ai donc dû en passer par la compilation.

    La documentation de mod_wsgi est très bien faite et elle explique bien les problèmes que l’on peut rencontrer avec MacOSX [en], essentiellement dû au fait que MacOSX supporte 4 architectures (PPC7400 — 32 bits —, PPC64 — 64 bits —, i386 — 32 bits— et x86_64 — 64 bits) mais que tous les programmes ne sont pas forcément distribués avec les 4 codes. En l’occurence, Apache et Python ont été compilé en i386 uniquement… mais voilà, même si on lui indique le chemin de Python a utilisé, le compilateur va chercher à un moment donné celui installé par défaut. En l’occurence, il s’agit d’une installation via MacPython, effectuée sur mon précédent Mac, avec un code PPC7400. Il m’a fallu un peu de temps avant de m’en rendre compte et remplacer le fichier PPC par un fichier i386 et permettre à la compilation de se terminer.

    Du coup, entre temps, j’ai installé mod_python pour pouvoir avancer un peu sur la configuration de django via Apache. Pas de remarque particulière, l’installation se fait sans difficulté via MacPort et la configuration ne m’a pas posé de problème particulier, y compris l’authentification HTTP via Apache, django proposant un backend [en] pour cela. Ceci étant, ce n’était qu’une solution très provisoire, car mod_python ne permet pas d’utiliser Mercurial via django. En effet, le principe de django_hg est d’utiliser la requête django pour construire une requête Mercurial qui est en fait une requête wsgi. Ca fonctionne avec le serveur de développement de django car celui-ci est également wsgi. Évidemment, ce n’est pas le cas lorsque django est servi via mod_python.

    D’où mon retour sur mod_wsgi. Une fois la compilation réussie, la configuration m’a donné un peu de mal également. En fait, là aussi, la doc est très claire, encore faut-il penser à vérifier le chemin de django. En effet, si django n’est pas dans le path du dossier où est exécuté le script wsgi, il faut ajouter django à l’aide de sys.path.append("/chemin/vers/django/"). Cependant, le piège par rapport aux exemples de la doc, c’est qu’avec MacPort, django est installé dans opt/local/lib/python2.5/site-packages/django/bin/. Or si on inclue juste opt/local/lib/python2.5/site-packages/django/, on peut inclure django, accéder aux settings, mais le script crash après. Mais si l’on lit bien la documentation, il est bien précisé qu’il faut mettre le chemin où se situe django-admin.py. Voilà qui m’apprendra à lire les documentations au pied de la lettre !

    Cela fait, le reste a été un jeu d’enfant, mais je réserve le détail à un prochain article.

    Text
    6 months ago
  3. django_hg sait cloner

    J’ai profité du pont pour travailler sur l’un des points qui me semblait le plus critique dans django_hg, la gestion par django des requêtes HTTP utilisées pour cloner (et pour puller.)

    Je dois dire que cela s’est très bien passé, bien plus que je ne l’aurai pensé, grâce notamment à l’aide de la mailing-list (et en particulier de Dirkjan Ochtman [en] et Benoît Boussicot [en].) En fait, ce qui m’a le plus retenu, c’est que je m’attendais tellement à galérer que j’ai fait des erreurs bêtes et tout développeur sait bien que ce sont les erreurs les plus évidentes qui sont les plus difficiles à corriger !

    Faire traiter par django les requêtes d’un clone est donc très simple:

    # views.py
    def commands(request, name): 
        """ handles the commands sended by an hg client (clone, pull, push) 
        ``name`` 
            the name of the repository 
        """
        from mercurial import hg, ui 
        from mercurial.hgweb.request import wsgirequest 
        from mercurial.hgweb import protocol 
    
        cmds = ['between', 'branches', 'capabilities', 'changegroupsubset', 'heads'] 
        r = hg.repository(ui.ui(), name) 
        req = wsgirequest(request.META, None) 
    
        if request.GET.get('cmd') in cmds: 
            resp = protocol.__getattribute__(request.GET.get('cmd'))(r, req) 
    
        return HttpResponse(resp, protocol.HGTYPE)
    

    Les imports correspondent aux différents objets de Mercurial. On note en particulier que les requêtes sont des objets wsgirequest. Cela tombe bien, django aussi, à ceci prêt que la request django engloble les données nécessaires à la création d’une requête wsgi dans le dictionnaire request.META.)

    La liste des commandes disponibles est décrite dans cmds. Il suffit de créer en plus un objet repository r et après avoir vérifié que la commande est bien une des commandes attendues par l’objet protocol qui gère toutes les étapes [en] d’un clone, on obtient un flux qu’il suffit de retourner à Mercurial avec le bon type MIME, avec l’objet HttpResponse de django, dont l’inclusion se fait au niveau du module.

    Simplissime, non ? Vous pouvez voir le code en situation sur bitbucket [en].

    Ce code ne gère pas l’authentification. Je compte me pencher sur la question cette semaine, même si auparavant, je voudrais me pencher un peu sur ce blog qui est un peu en vrac depuis que Free, sur lequel j’héberge encore les images, est en carafe…

    Text
    6 months ago
  4. django_hg

    Je viens de mettre à disposition django_hg [en] sur bitbucket [en].

    L’objectif de django_hg est de permettre la visualisation dans un projet django [en] d’un repository Mercurial [en].

    Si vous connaissez un peu Mercurial, vous savez qu’un serveur web est intégré par défaut. Pourquoi donc refaire ce qui existe déjà ?

    • Pour apprendre Python !
    • Pour apprendre django !!
    • Pour apprendre Mercurial !!! Sur ces points, je trouve que ça se passe plutôt bien, dans l’ensemble, pas trop de galère, à part la mise en place des doctests sur les templatetags.
    • et aussi parce que je pense qu’il est plus facile d’adapter des templates django que ceux de Mercurial,
    • parce qu’à terme je souhaite ajouter des fonctions telles que l’intégration de l’authentification django. Cela va d’ailleurs être mon prochain travail, en me basant sur django-projectmgr [en].
    Text
    7 months ago
  5. Referencrz updated

    Il y a quelques semaines, j’ai conçu un petit script chargé de convertir mes fichiers markdown[en] en HTML.

    py-markdown ayant été mis à jour, j’ai profité de l’occasion pour apporter quelques unes des modifications dont je parlais la dernière fois [fr]

    J’utilise finalement le système de génération des tables des matières de py-markdown. Un problème en moins à gérer, c’est toujours ça de pris. Par contre, l’extension TOC comporte un bug au niveau de l’indentation:

    # 1 
    ## 1-1
    ## 1-2
    ### 1-2-1
    ### 1-2-2
    # 2
    

    va donner

    <ul>
      <li>1
        <ul>
          <li>1-1</li>
          <li>1-2
            <ul>
              <li>1-2-1</li>
              <li>1-2-2</li>
            </ul>
          </li>
          <li>2</li>
        <ul>
      </li>
    </ul>
    

    au lieu de :

    <ul>
      <li>1
        <ul>
          <li>1-1</li>
          <li>1-2
            <ul>
              <li>1-2-1</li>
              <li>1-2-2</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>2</li>
    </ul>
    

    Il faut que je trouve le temps de déposer un ticket.

    Par ailleurs, j’ai ajouté la coloration syntaxique à l’aide de Pygment.

    Le script est téléchargeable ici [en], avec désormais des feuilles de styles de base pour la mise en page et pour la coloration du code.

    Text
    8 months ago
  6. Sortie d'apnée

    Je viens de passer un mois et demi à bosser comme une brute, notamment à réaliser un CMS avec symfony 1.2 + doctrine + jQuery (je reviendrai là dessus bientôt.)

    J’ai donc eu peu de temps libre, mais j’ai quand réussi à lire Sandman [fr] de Neil Gaiman [fr] (une lecture logique après avoir lu American Gods[fr] et Culture Libre [fr] de Lawrence Lessing [fr].

    Le premier est proche d’American Gods par son côté “Rock n’ roll”. Sandman, le héros, m’évoque Alice Cooper ou à Robert Smith, selon le dessinateur. Et Méphistophélès ressemble étrangement à David Bowie… À part ça, je ne suis pas trop fan de ce genre de récit (les épisodes des X-Men avec Belasco ou encore les aventures du Dr Strange m’ennuyaient quand j’étais adolescent…)

    Le second n’est pas un roman, mais plutôt un essai politique. Alors que la loi Hadopi est discutée en ce moment à l’Assemblée Nationale, la lecture de ce livre montre combien cette loi (et toutes celles du même genre) semble vouée à l’échec. Il montre aussi la très grande hypocrisie de l’industrie de la culture, qui après s’être créée grâce au piratage, s’insurge contre les nouveaux usages dès lors qu’ils vont à son encontre. Très documenté mais en même temps très simple à lire (les traducteurs ont fait un énorme travail bénévole), je pense que toute personne qui s’intéresse à l’avenir la culture doit le lire. Vous pouvez le télécharger ici [fr]

    J’ai aussi réalisé mon premier script Python, suite au post [fr] de David Larlet [fr]. Il s’agit d’un petit script qui convertit des fichiers markdown[en] en HTML à l’aide de py-markdown, pour faire une doc utilisateur par exemple. L’expérience est enrichissante, et David a raison de dire que l’on peut obtenir un résultat sympa en quelques heures. Par contre, je ne comprend toujours pourquoi il faut que je convertisse mon contenu en UTF-8, alors que mes fichiers et mon script sont en UTF-8 ? Le code en lui-même est évidemment très perfectible, et j’espère pouvoir le travailler un peu. J’ai comparé mon code avec celui de deliciousbackup de Nicolas Steinmetz [fr] et compte améliorer l’initialisation et refactoriser le tout dans une classe pour supprimer la variable globale. Je cherche aussi une solution pour générer une table des matières. J’ai dans un premier temps chercher à générer la table des matières à partir des entêtes <H1>, <H2>, etc. avec HTMLParser [en]. Le problème est que HTMLParser ne permet pas de modifier le contenu analysé. Je me suis donc tourné vers ElementTree [en], mais impossible de lui faire lire le HTML généré par py-markdown. Peut-être n’est-il pas valide (ElementTree est avant tout un parse XML), aussi l’ai-je abandonné pour Beautiful Soup [en], librairie connue pour justement ne pas être trop regardante sur la validité du HTML à analyser, au détriment de la lenteur (cela reste parfaitement acceptable pour l’usage que j’en ai.) Pour l’instant j’arrive à lire l’arbre et à le modifier, reste à renvoyer le tout, mais entre temps, j’ai vu qu’il y a une extension à py-markdown qui permet de gérer une table des matières. Du coup, je ne sais pas quelle solution je vais choisir…

    Text
    8 months ago
  7. An Introduction to Using CouchDB with Django

    Un exemple d’utilisation de CouchDB avec django, le framework python.

    Cet article est le dernier d’une série de 5 visant à expliquer le couplage lâche de django et son intérêt.

    Link
    1 year ago