Je me suis mis dans l'idée hier de permettre à Mozilla Thunderbird d'utiliser un annuaire d'entreprise non basé sur LDAP, mais sur une base Mysql.
Cet article me permet de faire le point sur le sujet et de livrer le fruit de mes recherches à la Communauté du Libre gourmande de moulinettes en tout genre qui relèguent la pierre philosophale au rang des inventions inutiles et idiotes.

Mozilla Thunderbird peut rechercher des adresses mails dans différentes sources :
- Dans un annuaire LDAP (Outils - Options - Rédaction - Adressage - Serveur D'annuaire)
- Dans le carnet d'adresses "par défaut" (abook.mab dans le profil de Thunderbird)
- Dans les adresses collectées automatiquement (les gens qui vous écrivent et ceux à qui vous écrivez : history.mab dans le profil de Thunderbird)
- Dans tout autre carnet d'adresses personnel, créé par l'utilisateur et figurant en *.mab dans le profil de Thunderbird

Jusqu'ici, nous étions sous Exchange, qui malgré ses défauts, propose une entrée LDAP dans son annuaire, je n'avais donc pas à me soucier de l'intégration de l'annuaire d'entreprise dans Thunderbird.
Aujourd'hui, nous avons migré vers une solution de messagerie et travail collaboratif basée sur des briques libres, et notamment sur Mysql qui renferme le carnet d'adresses et les utilisateurs dans une base à laquelle Postfix fait appel. Plus d'annuaire LDAP, donc plus d'annuaire d'entreprise sous Thunderbird, et donc : problème.

Je vous passe les détails qui m'ont fait arriver à la conclusion suivante : il faut que j'arrive à partager un carnet d'adresses Thunderbird qui sera généré régulièrement par un script PHP qui attaque la base Mysql. Et à partir de là, le problème se scinde en deux :

1. Partager un carnet d'adresses avec Thunderbird

Fort heureusement, d'autres se sont posés la question avant moi et je n'ai eu qu'à tester et approuver leur solution : utiliser l'extension AddressBooksSynchronizer qui permet au démarrage et à la fermeture de Thunderbird, ainsi qu'à n'importe quel moment en le forçant, de récupérer un carnet d'adresses distant (sur un lecteur réseau, via ftp, http, https ou même IMAP), ou au contraire de publier un carnet d'adresses de Thunderbird.

Il s'agit d'une bête copie de fichier .MAB sans intelligence aucune (pas de synchronisation différentielle, ni de détection des manquants ou des nouveaux : on écrase la cible avec la source, un point c'est tout). Et c'est précisément ce qu'il me fallait pour mon annuaire d'entreprise : un carnet d'adresses généré quelque part par "quelque chose" et que tous les utilisateurs vont piocher au démarrage de leur Thunderbird.
Restait à trouver ou à fabriquer le "quelque chose" en question.

2. Générer un .MAB à partir de Mysql

Là, ce fut plus compliqué, car à part un logiciel (certes gratuit, mais dont le code n'est pas fourni) intitulé Dawn qui sait transformer toute sorte de choses en .MAB, je n'ai pas réussi à mettre la main sur un script qui sache produire du .MAB (en fait, le format d'un fichier .MAB s'appelle Mork).
Innocent que j'étais encore hier, je me disait qu'un format de fichier utilisé par un logiciel libre à succès comme Thunderbird ne pouvait être que clair, efficace et fort bien documenté. Je suis donc parti à la recherche d'une description dudit format .MAB , et là, je n'ai pas été déçu !
C'est apparemment de notoriété public un truc purement incompréhensible.
Pourtant, le format est utilisé dans Thunderbird et Firefox, pour stocker des carnet d'adresses, mais aussi des historiques de navigation. C'est un ingénieur de feu-Netscape, David McCusker, qui, à l'époque, avait pondu ce ... truc censé être un "generic textual database file format "loosely inspired by LISP"... Ça fait froid dans le dos...

Evidemment la grammaire du langage utilisé ne nous aide pas beaucoup, tout juste on s'assure que la chose est vraiment imbitable, illisible par un humain et parfaitement ignoble à décrypter, même avec un logiciel dédié.
Jamie Zawinski, qui semble être le seul à avoir pondu un parser mork en perl qui permet de lire le contenu d'un fichier mork, n'y va d'ailleurs pas par quatre chemins, je le cite (en traduisant) :
Deux espaces de noms numériques qui se chevauchent, encodage des caractères spéciaux tantôt par anti-slash, tantôt par encodage hexadécimal avec un "$", "//" utilisé tantôt comme déclaration de commentaires (comme en c++), tantôt dans les adresses URL (NdT : ben oui : http://), compression des données désastreuses (*3 ou *6 !), non lisible par un humain, non éditable à la main, le seul avantage est qu'il utilise des lignes courtes et aucun caractères binaires, ce qui a pour effet d'augmenter sensiblement la taille des fichiers !

Malheureusement, moi, ce n'était pas d'un parser, dont j'avais besoin, mais d'un code qui produit du mork, à partir d'une base Mysql. Et je dois dire qu'à la lecture de tout ceci, j'ai failli abandonner.
J'ai quand même tenté la bonne vieille méthode de reverse-engineering, en créant un carnet d'adresses basique avec un seul nom à l'intérieur, pour voir à quoi ressemblait alors le .MAB. Cela mérite un petit copier-coller, voici donc un carnet d'adresses avec une seule adresse à l'intérieur, tel qu'il est généré par Thunderbird :



Je vous ai mis des couleurs pour que vous compreniez tout au premier coup d'oeil. C'est clair, hein ?!

Nous avons donc en rouge la description du fichier et des colonnes qui sont gérées par la base de données qu'il représente. Il suffit de faire un bête copier-coller de cette partie là, qui ne change pas d'un .MAB à l'autre.
La zone en bleue semble décrire les informations qui vont suivre. Là encore, quand on ne sait pas, on se contente de copier-coller.
En vert, vous retrouvez les données réelles, Nom, Prénom et Adresse mail du contact que j'ai saisi, ainsi que le numéro de téléphone. Ces données sont mises dans des cellules, qui sont numérotées de 81 à 88, en commençant par 88, pour faire un genre. Notez aussi le codage rigolo avec des "$" pour les caractères accentués.
En dessous, en violet, l'affectation des cellules aux colonnes décrites au-dessus. (^84^82) signifie naturellement, que dans la colonne numérotée 84 ("LastName"), vous allez mettre la donnée numérotée 82 ("Nom"). Comme j'ai saisi très peu de renseignement pour ce contact, la plupart des colonnes sont remplies de vide : (^AB=) signifie par exemple que cet enregistrement n'a pas de "Anniversary Month"
Je vous passe les petits mots de liaison qui sont restés en noir ci-dessus, tellement j'ai été incapable de résumer leur utilité.

Quand on saisi un second contact, la structure du fichier change un peu, ce qui montre toute l'absurdité, toute la souplesse du code mork généré par Thunderbird. Une fois que j'ai trouvé une structure qui me plaisait, je me suis fixé dessus, et j'ai tenté d'écrire un code PHP qui produit un fichier mork soluble dans Thunderbird. Et chose incroyable, j'ai réussi. Cliquez ici pour voir le code source commenté.

Le tour était joué, il ne me restait plus qu'à poser un cron sur mon script PHP pour qu'il génère régulièrement un annuaire d'entreprise à jour, à partir de la base Mysql, et à paramétrer l'extension de Thunderbird pour qu'elle aille chercher le .MAB généré à chaque ouverture du courrielleur. La synchronisation dans l'autre sens ne m'intéresse pas pour l'instant (heureusement : c'est encore un autre casse-tête !).



Y a pas à dire, quand on joue avec des logiciels libres, on finit toujours par arriver à nos fins et comme c'est en général très compliqué, on est encore plus fiers de nous au final. Ben oui : avec Exchange et Outlook, tout ceci est immédiatement fonctionnel, c'est même pas drôle...