Fichiers et sockets

Les trucs dont le chemin d'accès commence par un / correspondent aux fichiers sur le disque, avec lesquels on interragit directement par les outils classiques habituels. Les chemins $HOME, $DESKTOP, $DOWNLOAD, $MUSIC, $PICTURES, $PUBLICSHARE, $DOCUMENTS, $VIDEOS et $TEMPLATES (en majuscules) sont automatiquement remplacés par le chemin correspondant.

FIXME : je remarque que j'ai mis $PWD aussi, mais ça c'est un peu casse-gueule, vu que si on change de répertoire courant après avoir chargé un truc, ça continuera de pointer au même endroit. À voir…

Un fichier possède toujours au moins les clefs « name » (nom du fichier dans son répertoire) et « path » (chemin d'accès absolu au fichier), ainsi que « time » (date de dernière modification, ou -1 si le fichier n'existe pas). Si le fichier existe, les clefs suivantes sont ajoutées autant que possible :

Un truc de type fichier peut ou pas présenter les états « readable », « writable » et « executable » selon ses droits d'accès, et présente l'état « hidden » si son nom commence par un « . ». L'état « empty » est donné au fichiers de 0 octets ou aux répertoires ne contenant aucun fichiers. Les requêtes pouvant être reconnues sont les suivantes :

Notons que pour toute requête provoquant la création d'un fichier (de même que pour la méthode write), le répertoire parent est automatiquement créé s'il n'existait pas. En revanche, un fichier déjà existant ne sera pas remplacé. Contrairement à la plupart des autres sortes de trucs, les fichiers ont donc la particularité d'avoir certaines requêtes qui ne fonctionnent que s'ils n'existent pas encore.

Les méthodes read/stream/write permettent d'interagir avec le contenu du fichier si celui-ci est un fichier normal (elles n'ont pas d'effets sur les répertoires). Si le fichier est une socket, write tente d'envoyer un message sur cette socket, et read et stream renvoient, après tentative de connexion si besoin, une mise en cache du dernier message reçu (la commande thing CHEMIN -r/-w permet donc d'interagir en ligne de commande avec une socket, ce que je ne sais pas faire en shell par ailleurs).

L'attribut « control » d'un truc de type fichier est un objet particulier, qui va dynamiquement changer de type en fonction du type mime du fichier afin d'offrir des fonctionnalités adaptées. Il pourrait ainsi permettre d'ajouter de nouvelles clefs ou de nouveaux états en lisant d'autres méta-données (par exemple la taille d'une image ou la liste des fichiers dans une archive), mais rien de ce genre n'est encore implémenté (TODO).

Si le fichier est un lien symbolique, l'objet control possède un attribut « target » qui renvoie le truc correspondant au chemin réel. Si le fichier n'existe pas, l'objet control peut être utilisé comme un décorateur pour créer une socket STREAM. La fonction passée à ce décorateur recevra chaque nouveau client accompagné des informations associées, et devra renvoyer deux booléens, le premier indiquant s'il faut référencer ce client en lecture (un thread sera créé pour écouter ses envois) et en écriture (il recevra automatiquement tout message envoyé par write). Renvoyer faux dans les deux cas ne ferme pas la connexion et permet une gestion manuelle. Le déclenchement d'une exception, en revanche, ferme la connexion.

Un lien symbolique pointant vers un chemin invalide est considéré comme un fichier existant, dans la mesure où il occupe la place et empêche de créer autre chose. Toutefois, l'objet control possède lui aussi une méthode __bool__ qui permet de tester si le fichier existe bien en pratique (elle renvoie faux pour les liens invalides et pour les sockets auxquelles il est impossible de se connecter).

TODO : actuellement, l'écoute de fichiers se fait par une simple revérification des méta-données à chaque seconde (particulièrement la date de dernière modification). Ça n'a pas l'air d'impacter spécialement les perfs (notamment parce que le nombre de fichiers surveillés reste assez faible), donc ça n'a rien de prioritaire, mais ça pourrait éventuellement être une idée de remplacer ça par inotify dans les cas où une bibliothèque compatible est disponible.