Bloxool (blog de formation)

Réflexion ayant mené à bloxool

  • Après plusieurs recherches, il est évident que créer des signatures détachées est délicat (FireGPG ne le fait pas, copier-coller le billet dans un éditeur de texte, signer puis copier-coller la signature risque de provoquer des erreurs (un saut de ligne en trop, en moins, fin de ligne différent, …) → Donc on fait une signature enveloppée (wrapped sign) avec FireGPG.
  • Prévoir la possibilité d'importer les clés publiques, il semble que l'extension gnupg de php ne va pas chercher les clés sur les serveurs (à vérifier).
  • Pour chaque billet, il y'a un fichier texte original et une série de fichiers textes contenant les signatures.
  • Le texte, avant signature, doit contenir la date, l'auteur et le contenu.
  • Le fichier source est signé.
  • Chaque utilisateur a un fichier d'index de ses billets.

SVN : http://www.tchetch.net/svn/bloxool/trunk/, WebSVN

Les uuid

Les billets reçoivent un identifiant unique universel (uuid), pour se faire la fonction présentée par mimec fera parfaitement l'affaire (code php) :

function uuid()
{
    return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
        mt_rand( 0, 0x0fff ) | 0x4000,
        mt_rand( 0, 0x3fff ) | 0x8000,
        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) );
}

Structure du stockage

Les données du blog sont contenues intégralement dans un répertoire afin de simplifier la gestion des droits. À la racine de ce répertoire on trouve 256 répertoires nommés de 00 à ff. On y trouve aussi les fichiers d'index (index des billets, index des utilisateurs et index des tags1)).

Un billet est un répertoire ayant comme nom un identifiant unique universel (uuid), contenant les diverses fichiers composants du billet (soit la source du billet, nommé document.txt2), et les diverses signatures.

Le répertoire locks va contenir les verrous sur les fichiers.

 DATADIR/
    |
    + index.txt
    + user_index.txt
    + tag.txt
    |
    + 00/
    + 01/
    + 02/
    [...]
    + 09/
    + a0/
    + a1/
    [...]
    + fc/
    | + fc1b24b7-59e0-4935-88f2-06a6fde922d8
    | | + document.txt
    | | + document_000000.txt.asc
    | | |
    | | [...]
    | |
    | [...]
    |
    + fd/
    + fe/
    + ff/
    + locks/

Structure du document

Le document contient suffisamment d'informations pour reconstruire les différents fichiers d'index. On y trouvera, placé entre des balises «< et »>, les labels (sans espace) suivi de la valeur. L'espace servant à délimiter les éléments.

Le langage du document est le creole.

<<<author:uid tchetch>>>
<<<author:localuid 000001>>>
<<<author:uri ldap://www.tchetch.net/uid=tchetch,ou=users,o=tchetch>>>
<<<author:name Pierre Paul>>>
<<<date:creation 1994-11-05T13:15:30Z>>>
<<<date:lastmod 1994-12-05T15:02:53Z>>>
<<<tag blibli,blabla bla,bloblo,blou blou blou>>>

====== Blablabla ======

blablablablab
  * blabalbla
  * blablbla

===== Bliblibli =====

Bliblibli :
  $ ls
  a b c d

bliblibli __bliblibli__

Les signatures

Les signatures du fichiers sont stockées dans des fichiers nommé document_XXXXXX.txt.asc ou XXXXXX correspond à l'identifiant local de l'utilisateur ayant produit la signature.

Les signatures sont simplement des signatures en texte clair.

Fichier d'index

Le fichier d'index, index.txt, permet de retrouver “rapidement” un poste suivant la date de parution ou l'auteur. Il s'agit d'un simple fichier texte contenant une entrée par ligne. Chaque entrée est de la même longueur. Pour ce faire l'auteur est réduit à une simple valeur hexadécimal sur 6 caractères. La relation entre l'auteur et cette valeur, une fichier d'index des utilisateurs est tenu à jour.

Le fichier d'index à la structure suivante :

date_iso8601;user_local_id;uuid
  • Le profile de la date ISO 8601 (date_iso8601) est toujours UTC avec le temps en seconde : 1994-11-05T13:15:30Z, soit 20 caractères ASCII.
  • L'identifiant local de l'utilisateur (user_local_id) est composé de 6 caractères hexadécimaux : 000001, soit 6 caractères ASCII.
  • L'identifiant unique universel (uuid) est une suite de 32 caractères héxadécimaux séparé en 5 groupes par des traits d'union : fc1b24b7-59e0-4935-88f2-06a6fde922d8, soit 36 caractères ASCII.

Un enregistrement dans le fichier représente donc 62 caractères ASCII, plus 2 séparateurs (point-virgule) et terminé par un retour à la ligne unix (LF). Un total de 65 caractères est donc nécessaire, soit 520 octets par enregistrement.

Fichier d'index des utilisateurs

Le fichier d'index des utilisateurs, user_index.txt, permet de faire la relation entre un utilisateur et son index local utilisé par le fichier d'index. Dès qu'un utilisateur s'authentifie sur le système, son index local est créé (s'il n'existe pas déjà). Ce fichier contient les informations suivantes :

user_local_id;display_name;uri
  • L'identifiant local de l'utilisateur déjà décrit plus haut.
  • Un nom affichable au format UTF-8 : Pîerrẽ Ŋaïę
  • Une URI pour récupérer des informations supplémentaires : ldap://www.tchetch.net/uid=tchetch,ou=users,o=tchetch

Le point-virgule est utilisé comme séparateur. La taille des enregistrements est variable.

Fichier de tag

Le fichier de tag à la structure suivante :

tag:uuid,uuid,uuid
  • Le tag est un texte libre en UTF-8 : Ħõn blog
  • Une liste d'identifiant des billets, séparé par une virgule

La séparation entre les deux champs est faites par un point-virgule.

Verrouillage des indexes

Mmmmh … La méthode utilisée par dokuwiki va être utilisée ici : DokuWiki io_lock.

Les verrous

  • Le fichier d'index est verrouillé à l'aide du verrou locks/index
  • Le fichier des tags est verrouillé à l'aide du verrou locks/tag
  • Le fichier d'index des utilisateurs est verrouillé à l'aide du verrou locks/iusers
  • Les fichier des billets sont verrouillé avec leur propre nom.

Création d'un billet

L'utilisateur accède à l'interface de création de billet, écrit son billet et le poste :

Écriture des données

  1. Générer l'uuid
  2. Créer le répertoire
  3. Ouvrir le fichier document.txt en mode écriture
  4. Écrire les en-tête du document (auteur, uuid, date, …)
  5. Écrire le corps du document
  6. Fermer document.txt

Modifier l'index

  1. Obtenir un verrou sur le fichier d'index
  2. Ouvrir le fichier d'index en mode ajout
  3. Ajouter la nouvelle entrée
  4. Fermer le fichier d'index
  5. Libérer le verrou du fichier index

Chargement de l'index des tag en mémoire

  1. Ouvrir le fichier de tag en lecture
  2. Lire et parser le fichier de tag entièrement en mémoire
  3. Fermer le fichier de tag
  4. Ajouter, en mémoire, l'uuid pour chaque tag

Réécrire le fichier de tag

FIXME Ici changer pour utiliser un fichier temporaire lors de la réécriture.

  1. Obtenir verrou sur le fichier de tag
  2. Ouvrir le fichier en mode écriture
  3. Réécrire le fichier depuis la mémoire
  4. Fermer le fichier
  5. Libérer le verrou

Suppression d'un billet

La fonctionnalité de suppression ne devrait pas exister, mais bon, au cas où :

Chargement de l'index des tag en mémoire

  1. Ouvrir le fichier de tag en lecture
  2. Lire et parser le fichier de tag entièrement en mémoire
  3. Fermer le fichier de tag
  4. Supprimer, en mémoire, l'uuid pour chaque tag

Réécrire le fichier de tag

FIXME Ici (aussi) changer pour utiliser un fichier temporaire lors de la réécriture.

  1. Obtenir verrou sur le fichier de tag
  2. Ouvrir le fichier en mode écriture
  3. Réécrire le fichier depuis la mémoire
  4. Fermer le fichier
  5. Libérer le verrou

… Pour faire court :

On recherche l'uuid dans le fichier d'index, une fois la position de départ trouvée, on copie la partie avant et la partie après dans un fichier temporaire (appelle système pour ça), un fois le fichier temporaire créer, on verrouille l'index, copie le fichier temporaire à la place de l'index. Finalement il ne reste plus qu'à supprimer le répertoire du billet (et son contenu).

Modifier un billet

Aucun fichier d'index n'est touché par cette opération. Si il y a des signatures présentes, ne pas les supprimer (possibilités de faire un “diff” entre le document signé et le document actuel). Si la personne souhaite signer le nouveau document, juste remplacer le fichier de signature. Les opérations de réécriture d'un billet ou d'une signature font l'objet d'un verrouillage en bonne et due forme.

Lire un billet

Pas tellement besoin d'explication. Si un verrou est mis sur le fichier, attendre un moment et réessayer. Au bout de trois essais, échouer (en envoyant discrètement un mail à l'admin pour lui dire que c'est tout foutu).

Chercher un billet

Pas tellement besoin d'explication non-plus … quoique …

Par tags

Le principe est assez simple, on lit le fichier de tag ligne par ligne (si celui-ci n'est pas verrouillé) jusqu'à ce que le tag soit trouvé. Quand celui-ci est trouvé, on a la liste des billets. On lit ensuite chaque billet jusqu'à trouver un titre et on affiche les résultats. On peut prendre en compte les données de création, d'auteur, …

Par utilisateurs ou par date

Même principe que pour la recherche par tag. Il est a noté que le fichier d'index aura, logiquement, le billet le plus récent à la fin, donc une lecture par la fin serait plus intéressante. Comme les enregistrements dans le fichier d'index sont de longueur fixe, on peut facilement savoir le nombre de billets totaux et ainsi simplement faire de la pagination.

On peut admettre qu'un processus de réorganisation de l'index soit lancé durant la nuit afin de garantir un organisation par date.

Tous les billets d'un utilisateur

Il est envisageable d'avoir une la liste des billet par utilisateur un fichier d'index par utilisateur. Pour se faire, on ajouterai un fichier dans l'arborescence des billet ayant l'identifiant local de l'utilisateur. Les uuid de chaque billet créer par l'utilisateur seraient ajoutés à la suite dans ce fichier.

1) D'autres fichiers d'index peuvent être ajoutés par la suite si nécessaire
2) Ceci devrait être paramétrable via la configuration
 
formation/outils/blog/implementation.txt · Last modified: 2010/02/16 16:27 by tchetch
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Debian Driven by DokuWiki