Skip to main content

automatheque.renommage

Renommage et rangement de fichiers par gabarits.

Détail

Un gabarit est un squelette de chemin — {date:%Y}/{album}/{nom} — assorti d'une condition qui dit quand il s'applique et d'un ordre qui le priorise. Le renommeur choisit le premier gabarit applicable, en déduit un nouveau chemin, et y déplace le fichier.

C'est l'opération symétrique de automatheque.decomposition : là où celle-ci tire des métadonnées d'un chemin, celle-ci construit un chemin à partir de métadonnées. Les deux sont des distributions séparées parce que seule celle-ci écrit sur le disque : un consommateur qui indexe sans jamais déplacer n'a pas à en dépendre.

Les briques

  • Gabarit — un squelette, une condition, un ordre.
  • Gabarits — la liste des gabarits, et l'algorithme de choix : d'abord ceux dont la condition est vérifiée, classés par ordre, puis ceux qui n'ont pas de condition. Un gabarit sans condition est donc un filet de sécurité, pas un concurrent.
  • Renommable — mixin à faire hériter par l'objet à ranger. Il expose filename et surcharge _gabarits_par_defaut() et _liste_champs_dispo().
  • Renommeur — le déplacement lui-même.

Exemple

import attr

from automatheque.renommage import Gabarit, Gabarits, Renommable


@attr.s
class Photo(Renommable):
    album = attr.ib(default="", kw_only=True)
    annee = attr.ib(default="", kw_only=True)

    @classmethod
    def _gabarits_par_defaut(cls):
        return Gabarits(
            [
                Gabarit(
                    squelette="{annee}/{album}/{nom}", condition='"{album}"', ordre=1
                ),
                Gabarit(squelette="a-trier/{nom}", ordre=9),
            ]
        )

    def _liste_champs_dispo(self):
        return {"album": self.album, "annee": self.annee, "nom": ...}


photo = Photo(filename="/entree/DSC_0001.jpg", album="Japon", annee="2013")
photo.renomme("/photos")
# /photos/2013/Japon/DSC_0001.jpg

La configuration est reçue, pas cherchée

Les gabarits vivent souvent dans un fichier de configuration :

[renommage]
r1 = ['{annee}/{album}/{nom}', '"{album}"', 1]
r2 = ['a-trier/{nom}', '', 9]

Gabarits.depuis_configuration(config, section) les en tire, et le résultat est passé au renommeur :

gabarits = Gabarits.depuis_configuration(charge_configuration(), "renommage")
Renommeur(photo, gabarits=gabarits).renomme("/photos")

Le renommeur ne consulte aucun état global : c'est l'appelant qui décide d'où viennent ses gabarits. Le code d'origine appelait charge_configuration() lui-même — une localisation de service, qui rendait le renommage dépendant d'un fichier de configuration présent au bon endroit, et intestable sans lui.

Ce que le renommage ne fait pas

  • Il n'écrit pas d'attributs étendus. Le code d'origine posait discrètement user.automatheque.fichier_orig et user.automatheque.modele.classe dans les xattr du fichier, à chaque renommage. Les xattr ne survivent ni à la plupart des copies, ni aux archives, ni aux transferts réseau : c'est le plus fragile des supports pour de la provenance. Conserver le nom d'origine relève de l'application, qui sait où elle range ses métadonnées.
  • Il ne modifie pas le contenu du fichier. Écrire des étiquettes dans une image est l'affaire d'un adaptateur.

Transfert

Le déplacement est une copie, suivie d'une vérification de taille, suivie de la suppression de l'original. shutil.move seul ne dirait pas si la copie s'est mal passée d'un système de fichiers à l'autre ; ici, une cible qui ne correspond pas lève TransfertIncomplet, efface la cible douteuse et laisse l'original en place.

Les champs ne peuvent pas sortir du répertoire cible

Les champs d'un squelette viennent des métadonnées des fichiers traités — un album, une ville, un titre. Substitués tels quels, ils sortiraient du répertoire demandé : os.path.join jette son premier argument dès que le second est absolu, et .. remonte d'un niveau.

Chaque champ chaîne est donc assaini avant substitution — séparateurs neutralisés, segments . et .. remplacés. Les valeurs non-chaînes passent intactes, sans quoi {date:%Y} cesserait de fonctionner. Les séparateurs du squelette, eux, sont conservés : c'est par eux que tu décris ton arborescence.

En dernier recours, le chemin final est vérifié comme contenu dans le répertoire cible ; sinon CibleHorsRepertoire est levée sans rien déplacer. Un squelette absolu tombe donc sous cette garde.

Requirement

Python >=3.9

Installation

pip install automatheque.renommage

License

LGPLv3.0 ou ultérieure

Release files for automatheque.renommage 0.24.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for automatheque.renommage 0.24.0
File Size Uploaded
automatheque_renommage-0.24.0.tar.gz 33.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for automatheque.renommage 0.24.0
File Interpreter ABI Platform
automatheque_renommage-0.24.0-py3-none-any.whl Python 3 none any Details

Total release size: 63.4 kB

Release files / automatheque_renommage-0.24.0.tar.gz

Download URL automatheque_renommage-0.24.0.tar.gz
Size 33.9 kB
Tags Source
SHA-256 checksum
How to use checksums
10d735f178f8e44c811c43ca16839ec888490654b1b79d91fbaf63919ad61754
BLAKE2b-256 checksum
How to use checksums
b4fedfeb4fe7401d853350c6a8575ec6e17d1417be514c5e78f182ccc7b1b75a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.

Transparency log

Release files / automatheque_renommage-0.24.0-py3-none-any.whl

Download URL automatheque_renommage-0.24.0-py3-none-any.whl
Size 29.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17c2b849eed9250003061ec9a54eb14abcb4396d06432aee0df931f70ad57ba5
BLAKE2b-256 checksum
How to use checksums
99ecf5a2f23f934def24fd195e5078617f9270c26bdcde00c81660493337f6c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.

Transparency log

Release history Release notifications | RSS feed

0.24.1

2 release files

This release

0.24.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page