Mon ancien site est accessible à l'adresse suivante : http://old.harobed.org. En savoir plus…

Traduction du billet de Ian Bicking « À propos des librairies de génération de formulaires HTML »

En mars 2007, Ian Bicking a écrit un billet à propos des librairies de génération de formulaires web : « On form libraries »

J'ai trouvé ce billet très intéressant… bien que j'aie quelques commentaires à faire… mais cela fera l'objet d'un autre billet de ma part.

J'ai décidé de traduire ce document et voici le résultat ci-dessous.

Concernant la traduction, j'ai pris une assez grande liberté. J'ai retravaillé certaines phrases pour les rendre - je l'espère - plus simples à comprendre.
J'ai aussi pris certaines libertés au niveau de la mise en forme.
Mon document n'est donc pas une traduction fidèle, j'ai toutefois essayé de garder autant que possible l'esprit du billet original.
Traduction

À propos des librairies de génération de formulaires HTML

Il y a un certain temps (ntd - février 2005), j'ai écrit un billet à propos de la génération de formulaires web. J'y faisais part de mon expérience acquise lors du développement de FunFormKit, du développement des premières versions de FormEncode, et j'y expliquais aussi ce qu'est devenu FormEncode (uniquement une librairie de validation).

Depuis, sont arrivées quelques nouvelles librairies de génération de formulaires web dans l'écosystème Python; ToscaWidgets, Django newforms, et quelques autres dont j'ai entendu parler.
Je n'aime pas critiquer gratuitement le travail des autres, mais je tiens à dire que je pense que ces librairies ont adopté une mauvaise stratégie pour atteindre leurs objectifs.
Écrire une librairire de génération de formulaires est une tâche difficile. Il faut trouver le bon compromis entre une certaine simplicité d'utilisation et l'étendue des fonctionnalités.
Potentiellement, le nombre de fonctionnalités pour ce type d'outil est très élevé. Exemples :
  • comment modifier finement le code HTML généré ?
  • comment contrôler la mise en forme (le layout) ?
  • comment gérer la répétition d'éléments ?
  • comment gérer les éléments qui requièrent du Javascript ?
  • comment gérer les ressources coté serveur du type CSS ou Javascript ?
  • Comment gérer les communications client-serveur, par exemple supporter l'auto-complétion ?
Une librairie qui gère autant de fonctionnalités ne peut pas rester simple à utiliser. Une "petite" librairie qui reste simple ne pourra gérerer qu'une petite partie de ces fonctionnalités.
Cependant, pour générer des formulaires "simplistes", il n'est pas utile d'avoir recours à une librairie de génération de formulaires.

Cycle de vie de la création d'une librairie de génération de formulaires

Je vais maintenant expliquer pourquoi, à cause de leur conception, ils ne peuvent pas obtenir un bon compromis entre simplicité et fonctionnalité.
Il existe des problèmes qui n'ont pas de solution. Et contrairement aux apparences, c'est le cas des outils de générations de formulaires.
Le cycle de vie de création et de maintenance d'une librairie de génération de formulaires est pratiquement toujours le même.
Un développeur a certain besoins. Généralement il n'aime pas écrire du code HTML bien que cela ne le dérange pas de travailler avec un langage de template qui est plus difficile à utiliser. Il n'est sans doute pas très excité par les tâches manuelles et fabriquer une librairie de génération de formulaires est une agréable diversion.
Dans tous les cas, il fait le bon choix (enfin, celui qu'il pense être le bon) et il essaie d'utiliser une librairie existante.
Il se trouve que la librairie est complexe à utiliser, elle ne correspond pas à la façon dont il a appréhendé le problème, il est difficile d'identifier l'origine des erreurs, les petits ajustements qu'il souhaite apporter (lui, son chef ou son client) sont à l'origine de la plupart de ses difficultés.
Et là, il se dit « Je peux faire cela plus simplement ! ».
Le développeur a raison. Il sait exactement ce dont il a besoin (maintenant), et ce qui peut améliorer sa productivité.
Il crée donc une nouvelle librairie de génération de formulaires web.
Le problème est que la vie de cette nouvelle librairie ne s'arrête pas là. Elle ne peut pas s'arrêter là ! Pourquoi ? Parce que quelqu'un utilise cette librairie, et par conséquent le code doit être maintenu.
Une librairie de génération de formulaires est une chose difficile à maintenir, car elle a toujours besoin d'évoluer.
Des nouveaux types de champ doivent être ajoutés. Des nouveaux cas particuliers doivent être pris en compte. Pour ce qui concerne l'interface utilisateur, des cas particuliers, non prévus initialement, doivent pouvoir être traités.
Une bonne interface utilisateur est généralement spécifique au besoin, adapté au cas par cas. L'interface utilisateur doit être construite en fonction du besoin de l'utilisateur final et non pas en fonction des contraintes du développeur.
Avec le temps, le développeur a de nouveaux besoins.
Par exemple, une simple liste de cases à cocher contient un très grand nombres de choix. Il faut maintenant pouvoir l'afficher sur deux colonnes.
Conséquence : pour gérer ce nouveau cas, le développeur ajoute un peu de code à la fois dans la librairie et dans l'application.
Ensuite, le développeur souhaite que les champs textes contiennent le nom des champs (leurs labels) quand leurs contenus sont vides. Suite à cela, le système de validation devient un peu plus complexe à gérer.
Ensuite, le développeur aura peut être besoin de gérer des formulaires à plusieurs étapes… Ou alors des formulaires avec des champs optionnels…
De fil en aiguille, à chaque fois du code est ajouté à la librairie ainsi que dans l'application (à condition bien sûr, dans le meilleur des cas d'avoir le contrôle de ces deux parties).
Avec le temps, la librairie devient de plus en plus complexe, tandis que pendant ce temps, le développeur se familiarise avec son propre code et devient de plus en plus distant des autres développeurs qui devront peut être un jour intervenir dans son projet.
Et là, nous n'avons même pas abordé le sujet des non programmeurs qui souhaitent seulement modifier un tout petit peu le rendu HTML du formulaire. Ensuite vient le problème de turnover…

Et un jour, c'est la catastrophe, quelqu'un vient et dit « Je peux faire cela plus simplement ! » et c'est reparti pour un tour, on recommence l'histoire depuis le début.

Une autre approche

La partie validation
Je pense que le problème n'est pas pris par le bon coté. Je pense qu'il y a une meilleur approche, mais je suis trop fainéant pour la réaliser.
Bon…, je vais expliquer le principe, avec le petit espoir que quelqu'un réalisera le code :) .
Tout d'abord, la partie « validation » : j'aime la façon dont FormEncode fonctionne, je pense que la stratégie est bonne.
L'étape de validation est totalement indépendante du reste du système, vous pouvez programmer le type de validation que vous souhaitez, vous pouvez l'intégrer dans un autre système…
La partie « formulaire »
Ensuite, la partie « formulaire ».
La solution la plus simple est d'écrire directement le formulaire en code HTML avec son langage de template préféré.
Mais ceci est ennuyeux, les développeurs vont se plaindre… Pourquoi ?
  1. Remplir les valeurs par défauts dans les champs est ennuyeux. Il faut prendre en compte différents cas : les valeurs de la requête (par exemple en mode modification), les valeurs par défauts lorsque le formulaire est vide…
  2. La mise en place de l'affichage des messages d'erreurs est aussi une tâche ennuyeuse.
  3. Il faut écrire correctement les balises <label>… ce qui est une tâche rébarbative… c'est peut être ce qui explique que de très nombreux sites, même de grande notoriété, n'intègrent pas ces balises.
  4. Je suppose que l'HTML est généralement casse-pieds, bien que le langage soit seulement légérement plus verbeux que le code de programmation qui permet de le remplacer.
  5. La partie Javascript peut être ennuyeuse, beaucoup de développeurs web ne sont pas très à l'aise avec ce langage.
  6. Il est ennuyeux de placer correctement les fichiers ressources Javascript et CSS, et d'effectuer ensuite la liaison des classes CSS avec les bonnes balises…
  7. Les appels Ajax sont réellement ennuyeux à mettre en place.
  8. Les imbrications de champs, les répétitions de groupes de champs… sont une autre source d'ennuis.
  9. Et pour finir, il est difficile de réutiliser tout cela.
Ma réponse est que tous ces problèmes peuvent être résolus sans librairie de génération de formulaires.
formencode.htmlfill répond aux points 1 et 2. Ce n'est pas parfait, mais c'est utilisable.
Quelque chose comme WebHelpers peut être utile pour le point 4.
Aucun de ce ces outils ne doit être la solution ultime. Ils peuvent tous être améliorés mais attention, il ne faut pas pousser trop loin leurs perfectionnement ! Sinon ils vont devenir de trop grands consommateurs de temps.
Un peu de « Unobtrusive JavaScript » peut résoudre le problème numéro 5.
Je pense que la mise en oeuvre d'un outil spécifique pour le point 6, pourrait être pratique : j'imagine quelque chose comme <input type="date" js-require="DateInput"> qui chargerait automatiquement les bons fichiers Javascript et CSS, et qui appellerait du code là où est le champ DateInput.

Les nouvelles spécifications Web Forms 2.0 de WHAT-WG peuvent parfaitement gérer les points 7 et 8… un outil construit sur ce modèle ferait parfaitement l'affaire.

Une fois que vous avez tout cela, je pense que le point 9 peut être plus ou moins atteint.
En conclusion, vous n'avez pas besoin d'un framework de génération de formulaires, vous avez juste besoin d'un outil tout simple qui génère du code HTML et qui respecte certaine conventions.
Ce qui est remarquable , c'est que cette technique est uniquement basée sur des abstractions déjà présentes : HTML et Javascript.
De plus, chaque outil peut être utilisé de manière indépendante. Il est possible de remplacer chaque brique par autre chose, une nouvelle implémentation… qui correspond parfaitement au besoin du projet.
Ce qui est difficile à accepter, c'est que ces outils semblent terriblement simplistes, ils ont peu de fonctionnalités comparé aux systèmes de génération de formulaires automatique.
Doucement mais surement, ces petits outils peuvent gagner la course, quelque soit la manière… pendant ce temps, les autres systèmes de génération de formulaires vont souffrir du mal du cycle de la réimplémentation… Tandis que de simples outils vont mieux supporter les épreuves du temps.
Et même si ces simples outils n'arrivent pas à atteindre l'objectif souhaité, il est possible d'en remplacer un ou plusieurs sans mettre en péril tout l'édifice.

Maintenant, ça serait génial que quelqu'un se lance dans la fabrication des pièces manquantes, car j'essaie vraiment de ne pas commencer de nouveaux projets supplémentaires.

Ian Bicking

Depuis cette date, tous les outils décrits dans ce billet n'ont pas été réalisés. Toutefois formencode et formencode.htmlfill remplissent très bien leurs rôles respectifs.

Je tiens aussi à souligner que depuis, les librairies de génération de formulaires ont bien évolué, comme par exemple WTForms que j'ai étudié hier. Cette dernière reste très très simple d'utilisation.

Dans un prochain billet, je donnerai mon point vu personnel sur ce sujet.

Read and Post Comments

Donald Knuth un personnage atypique qui illustre bien le ''vrai'' esprit hacker / geek

Ces dernières semaines, j'étudiais un peu TeX, LaTeX … et j'en ai profité pour étudier l'histoire de ce projet.

Donald Knuth est l'auteur de TeX, c'est un très grand hacker, il a gagné de très nombreux prix, a écrit de nombreux livres de référence dont le plus connu est « The Art of Computer Programming ». J'adore la personalité atypique de ce hacker, son humour de geek… voici pourquoi…

Note : ce billet contient des extrais de phrases de wikipedia.

Création de TeX pour publier « The Art of Computer Programming »

En 1965 il finit d'écrire le premier jet d'un manuscrit de 3 000 pages qui deviendra par la suite le livre « The Art of Computer Programming ».

En 1976, Knuth prépara la seconde édition du volume 2, nécessitant d'être à nouveau mis en page. Mais le style de mise en page n'était plus disponible et le travail devait être refait. En 1977, Knuth décida de passer quelques mois pour travailler sur un nouvel outil. Huit ans plus tard, il avait achevé TeX, qui est depuis lors utilisé pour tous les volumes.

Je trouve cela très fort, Donald Knuth a besoin de faire un outil pour réaliser son livre.
Il met presque plus de temps à réaliser l'outil que le livre en lui même.
Je trouve que cela illustre bien l'esprit hacker… concevoir des outils pour faciliter l'exécution d'une tâche même si l'outil est plus long à réaliser que la tâche de départ (bon, dans cet exemple mon propos est approximatif mais l'idée reste là).

Une prime par faute / bug trouvé

Il offre une prime de 2,56 dollars pour chaque faute typographique ou erreur découverte dans ses livres sous prétexte que « 256 cents font un dollar hexadécimal »

Voici la liste des personnes récompensées : The Bank of San Serriffe.

Voici la page wikipedia consacrée aux chèques de récompenses envoyés par Donald Knuth : Knuth reward check.

Pour ce qui est de la chasse aux bugs dans TeX et Metafont, il a mis en place une prime de 2,56 dollars qui est doublé tous les ans, jusqu'à atteindre 327,68 dollars.

Je trouve cette démarche assez courageuse, l'auteur doit être sûr de son travail pour mettre en place ce type de prime.

Choix des numéros de version de ses projets

Ses choix de numérotation de version sont eux aussi atypiques :

  • Depuis la version 3 (actuellement 3.1415926), les numéros de version de TeX tendent vers PI !
    Ceci pour indiquer que le projet est stable, qu'aucune nouvelle fonctionnalité n'est acceptée, les nouvelles versions sont uniquement des corrections de bugs.
  • Dans le même esprit, Metafont a un numéro de version qui tend vers la constante de Néper : le numéro de version actuel est « 2.71828 ».

Après 15 ans d'utilisation du mail, il décide d'arrêter

Knuth a cessé d'utiliser le courrier électronique en prétendant qu'il s'en était servi entre 1975 et le 1er janvier 1990, et que cela suffisait pour toute une vie. Il trouve plus efficace de tenir une correspondance en « mode batch », et y consacrer une journée tous les trois mois, en répondant par courrier « classique ».

Je cite :

Email is a wonderful thing for people whose role in life is to be on top of things. But not for me; my role is to be on the bottom of things. What I do takes long hours of studying and uninterruptible concentration. I try to learn certain areas of computer science exhaustively; then I try to digest that knowledge into a form that is accessible to people who don't have time for such study.

On the other hand, I need to communicate with thousands of people all over the world as I write my books. I also want to be responsive to the people who read those books and have questions or comments. My goal is to do this communication efficiently, in batch mode --- like, one day every three months.

Conclusion

Si on me demande qu'est ce que l'esprit geek, qu'est ce qu'un hacker, je pense que je peux indiquer l'url de ce billet pour donner Donald Knuth en exemple.

Read and Post Comments

Mesures de bande passante de mon réseau local

Depuis un certain temps, je trouvais mon réseau Wifi très lent. La dernière fois que j'ai dû transférer 20 Mo entre deux portables, cela a pris 20 minutes !

Cette après midi, j'ai décidé d'étudier un peu plus précisément ce problème.

1. Utilisation de "netperf"

netperf est un outil de mesure de performances réseaux.

D'après la documentation, il permet de mesurer de nombreuses choses… pour ma part, je n'ai utilisé que les mesures TCP_STREAM et TCP_MAERTS.

netperf est disponible sous Debian (dans la section non-free) et sous Ubuntu.

Une fois le paquet installé, netserver est lancé automatiquement et écoute sur le port 12865.

Voici un exemple de ce que j'ai fait :

  • j'ai installé le paquet netserver sur la machine A et B
  • j'ai exécuté sur l'une des deux machines la commande suivante :
$ netperf -H 192.168.1.10 -t TCP_STREAM
TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.1.10 (192.168.1.10) port 0 AF_INET : demo
Recv   Send    Send
Socket Socket  Message  Elapsed
Size   Size    Size     Time     Throughput
bytes  bytes   bytes    secs.    10^6bits/sec

 87380  16384  16384    11.36       1.69

2. Mes mesures

J'ai donc utilisé netperf pour mesurer la bande passante mon réseau local dans un peu près toutes les configurations :

Source Destination Débit
Wifi / Ethernet Lieu Wifi / Ethernet Lieu Mbit/s Mo/s
Wifi (eeepc) Bureau Wifi (macbook) Bureau 0,01 0,00125
Wifi (eeepc) Proche de la freebox Wifi (macbook) Proche de la freebox 1,16 0,15
Wifi (macbook) Proche de la freebox Ethernet (PC fixe) - 6,36 0,795
Wifi (eeepc) Proche de la freebox Ethernet (PC fixe) - 1.52 0,19
Ethernet (eeepc) - Ethernet (PC fixe) - 94,03 11,75
Ethernet (macbook) - Ethernet (PC fixe) - 93.96 11,75

Pour avoir un ordre de grandeur, voici les valeurs maximales théorique de mon réseau :

  • Ethernet : 100 Mbit/s soit 12,5 Mo/s
  • Wifi IEEE 802.11g : 54 Mbit/s théoriques, 25 Mbit/s réels soit 3,125 Mo/s

On peut constater que le débit Wifi de mon réseau est catastrophique ! D'une incroyable lenteur entre wifi à wifi : 1,25 Ko/s !

Par contre, pas de problème au niveau du réseau Ethernet, je suis très proche des valeurs maximales de transfert.

Pour améliorer le wifi, j'ai essayé de changer de canal, étant donné qu'il y a de nombreux réseaux wifi dans ma zone.
Sur ma Freebox, la sélection du canal était activée en mode automatique :
« Si vous activez le choix automatique du canal, la Freebox choisira elle même, à chaque démarrage, le canal Wifi le moins perturbé. Cela vous permet d'obtenir une connexion plus fiable. »

J'ai choisi de le passer en manuel et de choisir le canal 2 après avoir vérifié avec wifi-radar que personne ne l'utilise dans ma zone. Après observation, je constate que tous les utilisateurs de Neuf sont sur le canal 11… et il y a du monde ! Je pense que leurs débits doivent être catastrophique.

Voici mes mesures après être passé sur le canal 2 :

Source Destination Débit
Wifi / Ethernet Lieu Wifi / Ethernet Lieu Mbit/s Mo/s
Wifi (eeepc) Bureau Wifi (macbook) Bureau 7,36 0,92
Wifi (eeepc) Proche de la freebox Wifi (macbook) Proche de la freebox 7,78 0.97
Wifi (macbook) Proche de la freebox Ethernet (PC fixe) - 20,66 2.58
Wifi (eeepc) Proche de la freebox Ethernet (PC fixe) - 22,41 2,8

Les résultats sont vraiment meilleurs, je suis presque aux valeurs maximales du Wifi.

Voici maintenant des mesures vers l'extérieur : un serveur situé chez un hébergeur.

Source Destination Débit
Wifi / Ethernet Lieu Wifi / Ethernet Lieu Mbit/s Mo/s
Ethernet (PC fixe) À mon domicile via ADSL Hébergeur 0.87 0,108
Ethernet (PC fixe) À mon lieu de travail via ADSL Hébergeur 0.84 0,105
via ADSL Hébergeur Ethernet (PC fixe) À mon domicile 5.49 0,686
Ethernet (Serveur A) Hébergeur A Ethernet (Serveur B) Hébergeur A 94.13 11,76

Voici les caratéristiques de ma ligne ADSL :

  • Votre ligne est raccordée à un DSLAM compatible ADSL2+
  • Longueur : 2159 mètres
  • Affaiblissement : 32 dB

Voici les caratéristiques de la ligne ADSL à mon lieu de travail :

  • Votre ligne est raccordée à un DSLAM compatible ADSL2+
  • Longueur : 1490 mètres
  • Affaiblissement : 22 dB

La bande passante maximale pour une connexion ADSL2+ :

  • en réception : 28 Mbit/s théoriques soit 16 Mbit/s en pratique
  • en émission : 1,2 Mbit/s théoriques
Read and Post Comments

php var_dump VS python repr !

Un exemple en Php :

<?php

$a = 'bar "test" bar';
var_dump($a);
// Sortie : string(14) "bar "test" bar"

$b = 'bar \'test\' bar';
var_dump($b);
// Sortie : string(14) "bar 'test' bar"

$c = 'bar \'test\' "test" bar';
var_dump($c);
// Sortie : string(21) "bar 'test' "test" bar"

$d = array(
    'foo' => 'bar \'test\' "test" bar'
);
var_dump($d);
/* Sortie :
    array(1) {
      ["foo"]=>
      string(21) "bar 'test' "test" bar"
    }
*/

?>

la sortie de ce script :

string(14) "bar "test" bar"
string(14) "bar 'test' bar"
string(21) "bar 'test' "test" bar"
array(1) {
  ["foo"]=>
  string(21) "bar 'test' "test" bar"
}

Même chose en Python :

>>> a = 'bar "test" bar'
>>> print(repr(a))
'bar "test" bar'

>>> b = 'bar \'test\' bar'
>>> print(repr(b))
"bar 'test' bar"

>>> c = 'bar \'test\' "test" bar'
>>> print(repr(c))
'bar \'test\' "test" bar'

>>> d = { 'foo': 'bar \'test\' "test" bar' }
>>> print(d)
{'foo': 'bar \'test\' "test" bar'}

Observatons :

  • PHP oublie d'afficher les caractères d'échappements
  • Python affiche correctement les caractères d'échappements
  • Python prend soin d'afficher au mieux les guillemets : soit utilise des simples "quotes" ou des "double quotes"
Read and Post Comments

Début mars 2010, Python, WSGI, WebDAV état des lieux

Plus de six mois après avoir publié mon dernier billet au sujet des serveurs WebDAV basés sur protocole WSGI (sous Python), il est tant pour moi de faire un nouveau point sur la situation.

1. J'ai choisi WsgiDAV

Au mois d'août dernier, je n'avais pas encore choisi entre le projet pywebdav et wsgidav. Depuis, j'ai fait mon choix, j'ai choisi wsgidav. Qu'est ce qui a motivé ce choix ?

  • l'architecture de wsgidav est modulaire, je trouve que l'utilisation de plusieurs middleware wsgi pour ajouter des fonctionnalités est une chose intéressante
  • comme son nom l'indique WsgiDAV est orienté WSGI ce qui est avantageux pour moi car c'est mon objectif premier et donc cela me donne moins de travail par rapport à pywebdav

2. Changements apportés à WsgiDAV

Lorsque je travaillais sur le projet pywebdav j'avais comme objectif d'apporter des modifications au code pour fournir une classe application ou middleware WSGI. Je n'ai plus à me préocuper de ce point car WsgiDAV est nativement orienté WSGI.

Par contre, depuis août j'ai tout de même apporté des améliorations à WsgiDAV. Ma plus importante contribution est la compatibilité avec le client WebDAV Finder de Apple.

2.1. Compatibilité avec Apple Finder WebDAV Client

C'est la tâche qui m'a pris le plus de temps et posé le plus de difficulté... bien que cela soit surtout dû à un manque de méthode et un surplus de procrastination.

Au niveau de la méthode, j'ai procédé à tâton pendant un certain moment. Je plaçais des logs, activais PDB... et j'essayais de de comprendre les causes d'incompatibilités avec Apple Finder.
J'ai ensuite utilisé Wireshark pour analyser les échanges TCP/IP... ce qui fut une très bonne idée car en quelques heures j'ai trouvé et corrigé les erreurs que je n'arrivais pas à déceler auparavant.
Parlons maintenant de ma procrastination... on va dire que j'ai tourné autour du problème pendant trois ou quatre mois, de septembre à décembre 2009.
Étant donné que je ne procédais pas avec la bonne méthode, je n'étais pas très motivé pour travailler sur cette tâche. J'avais toujours une bonne excuse pour travailler sur d'autres choses. Comme très souvent, la cause première de la procrastination est la peur de l'échec.

La bonne nouvelle est que maintenant les problèmes de compatibilités avec Apple Finder sont réglés. D'autre part, ces corrections ont aussi corrigé d'autres erreurs... avec Windows Vista si mes souvenirs sont bons.

3. Chantiers en cours

Depuis que les problèmes de compatibilités avec Apple Finder sont résolus, j'ai débuté d'autres chantiers...

3.1. Amélioration des tests

J'en ai marre de devoir utiliser Wireshark, un client WebDAV... pour tester mon code... j'ai donc décidé pour gagner du temps et de la qualité en regardant du coté des test fonctionnels... ce que j'aurais dû faire depuis le début !

En gros, WsgiDAV utilise trois types de tests :

  • un fichier de commande à lancer avec litmus (programme pour tester des serveurs Webdav)
  • utilisation de la librairie davclient
  • utilisation de paste.fixture.TestApp mais ce type de test est limité aux requêtes HTTP classiques GET, PUT, DELETE

Autre informations :

  • les tests utilisent le module standard unittest
  • il n'est pas toujours possible de lancer des tests individuellement, par exemple avec test_wsgidav_app.py il est obligatoire de lancer l'intégralité des fonctions de tests et dans le bon ordre

Mes objectifs et tâches en cours au niveau des tests :

  • utiliser l'outils Nose pour lancer les tests et supprimer petit à petit l'utilisation du module unittest
  • permettre de lancer les tests individuellement
  • fournir une classe davclient.TestApp dérivée de paste.fixture.TestApp qui permet de tester l'intégralité des fonctions Webdav.

Pour le moment ces tâches ne me posent pas trop de difficultés.

3.2. Support d'un provider "Mixin"

Dans un de mes projets d'utilisation de WsgiDAV, j'ai besoin de "monter" un dossier accessible via une url du type "http://exemple.com/dav/".

Petit détail, j'aimerais pouvoir voir le dossier "dav" (dossier virtuel nommé aussi "share_name") lorsque je me connecte à "http://exemple.com/". Cette fonctionnalité n'est pas existante actuellement.

Ce point est important pour deux choses :

  • simplifier la "découverte" des points de montages
  • Gnome Nautilus ne permet pas de visualiser une resource si la racine du domaine ne contient pas son dossier parent (c'est un bug que j'aimerais corriger à l'avenir). C'est à dire qu'il n'est pas possible d'accéder à "http://exemple.com/dav/" si la requête PROPFIND sur "http://exemple.com/" ne liste pas le dossier "dav"

Pour résoudre ce problème, j'ai décidé de créer un nouveau provider, que j'ai nommé "MixinProvider". Ce provider permet de "mixer" plusieurs "provider" en un seul.

Exemple d'utilisation :

provider = MixinProvider((
    (&quot;/&quot;, FilesystemProvider('/tmp/root1/')),
    (&quot;/&quot;, FilesystemProvider('/tmp/root2/')),
    (&quot;/dav&quot;, FilesystemProvider('/tmp/root3/')),
    (&quot;/foo/bar/&quot;, FilesystemProvider('/tmp/root3/'))
})

Note :

  • il est tout à fait possible de mélanger d'autres types de provider que FilesystemProvider
  • les providers sont traités dans l'ordre d'apparition de la liste (ici un tuple), c'est à dire que dans cet exemple, si les dossiers '/tmp/root1/' et '/tmp/root2/' contiennent tous les deux un fichier nommé "foobar.txt", si l'utilisateur exécute la requête GET '/foobar.txt', c'est le contenu du fichier '/tmp/root1/foobar.txt' qui sera retourné.

Actuellement, la classe MixinProvider est presque fonctionnelle.

3.3. Support d'un provider "Dummy"

Pour la réalisation de la classe MixinProvider j'ai eu besoin de créer un provider permettant de créer des ressources mais aussi surtout des dossiers fictifs… d'où le nom « Dummy ».

Voici un exemple d'utilisation de cette classe :

dummy_provider = DummyProvider(
    resources = ('/file1.txt', '/folder_a/file2.txt', '/file3.txt',),
    collections = ('/folder_b/', '/folder_c/folder_d/',)
)

Remarque : la classe MixinProvider crée automatiquement un provider "dummy" pour permettre la visualisation des points de montages lors de l'exécution de requêtes PROPFIND.

4. Chantiers futurs

Voici une liste d'autres chantiers futurs :

  • amélioration de la documentation : basé sur Sphinx, qui devra être hébergé sur http://packages.python.org/wsgidav/
  • amélioration des tests..., mise en place d'un buildbots...
  • rédiger une procédure de sortie de release : liste d'instructions à réaliser après chaque release stable. L'une de ces instructions serait de mettre à jour un tableau qui liste les clients webdav avec lesquels wsgidav est compatible.

5. En annexe du projet

À la marge du projet, j'ai réalisé un provider basé sur ZODB. Il fonctionne plutôt bien. Ce provider n'est pas libre pour le moment.

C'est dans le cadre de ce projet que j'ai eu besoin de créer le provider MixinProvider.

6. Temps passé sur le projet

Depuis août, on peut dire que j'ai travaillé en moyenne 3h par mois sur le projet... le problème est que j'y ai surtout passé de multiples petits moments... ce qui n'est pas ce qu'il y a de plus efficace... car la plupart du temps j'avais juste le temps de me replonger dans le code... avant d'arrêter.

Dans les semaines qui viennent, j'espère pouvoir travailler chaque dimanche quatre heures sur le projet afin de rapidement finir la partie provider Mixin (ce qui est presque réalisé).

Read and Post Comments

Billets plus anciens »

Consultez mes archives pour avoir une vue d'ensemble de mes anciens billets.