From 043d2ae63e42fb747cf12a0f65bff15612621bc4 Mon Sep 17 00:00:00 2001 From: Theo Satabin Date: Mon, 3 Nov 2025 17:39:41 +0100 Subject: [PATCH 1/2] Ajout de la conversion d'une liste de pyramide vers une heatmap --- CONTRIBUTING.md | 7 +- README.md | 22 +- README.pypi.md | 15 ++ src/rok4_tools/tmsizer.py | 15 +- .../tmsizer_utils/processors/map.py | 221 +++++++++++++++++- .../tmsizer_utils/processors/reduce.py | 6 +- 6 files changed, 272 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff54d46..235d04a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,12 @@ Merci d'envisager de contribuer à ce projet ! ## Git hooks -Nous utilisons les git hooks via [pre-commit](https://pre-commit.com/) pour appliquer et vérifier automatiquement certaines "règles". Veuillez l'installer avant de pousser un commit. +Nous utilisons les git hooks via [pre-commit](https://pre-commit.com/) pour appliquer et vérifier automatiquement certaines conventions. Veuillez l'installer avant de pousser un commit : + +``` +pip install pre-commit +pre-commit install +``` Voir le fichier de configuration correspondant : `.pre-commit-config.yaml`. diff --git a/README.md b/README.md index dcd415e..1b7d5bb 100644 --- a/README.md +++ b/README.md @@ -163,17 +163,23 @@ Utilisation : `tmsizer [-h] [--version] --tms [-i storage://pat Conversions possibles (paramètres obligatoires en gras, paramètres facultatifs en italique) : -| Format en entrée | Options d'entrée | Format en sortie | Options de sortie | Description | -|------------------|-------------------------------------------------------|------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| GETTILE_PARAMS | *`levels=[, ...]`*,*`layers=[, ...]`* | COUNT | | Compte le nombre de GetTile dans les URLs en entrée utilisant le TMS pivot et les éventuels niveaux et couches fournies | -| GETTILE_PARAMS | | SLAB | **`size=x[, ...]`*,*`layers=[, ...]`* | HEATMAP | **`bbox=,,, or area=`**, **`dimensions=x or level=`** | Génère une carte de chaleur des tuiles interrogées sur la zone demandée et sur les éventuels niveaux et couches fournies. Si un niveau est fourni en sortie, on calera la bbox et les résolutions pour avoir un pixel correpondant à l'étendue d'une tuile du niveau. Certaines aires sont prédéfinies pour certaines projections du TMS | -| GEOMETRY | **`format=`**,**`level=`** | GETTILE_PARAMS | | Génére les paramètres de requête GetTile des tuiles du niveau fourni intersectant les géométries en entrée | +| Format en entrée | Options d'entrée | Format en sortie | Options de sortie | Description | +|------------------|-----------------------------------------------------------------------------------------------------------|------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| GETTILE_PARAMS | *`levels=[, ...]`*,*`layers=[, ...]`* | COUNT | | Compte le nombre de GetTile dans les URLs en entrée utilisant le TMS pivot et les éventuels niveaux et couches fournies | +| GETTILE_PARAMS | | SLAB | **`size=x`**, **`storage=(FILE\|S3)`** | Génère les informations de la dalle contenant chaque tuile requêtée (indices et chemin de stockage) | +| GETTILE_PARAMS | *`levels=[, ...]`*,*`layers=[, ...]`* | HEATMAP | **`bbox=,,, or area=`**, **`dimensions=x or level=`** | Génère une carte de chaleur des tuiles interrogées sur la zone demandée et sur les éventuels niveaux et couches fournies. Si un niveau est fourni en sortie, on calera la bbox et les résolutions pour avoir un pixel correpondant à l'étendue d'une tuile du niveau. Certaines aires sont prédéfinies pour certaines projections du TMS | +| GEOMETRY | **`format=`**,**`level=`** | GETTILE_PARAMS | | Génére les paramètres de requête GetTile des tuiles du niveau fourni intersectant les géométries en entrée | +| PYRAMID_LIST | **`storage=(FILE\|S3)`**, `depth=` | SLAB | | Génère les informations de la dalle à partir d'une ligne de fichier liste de pyramide | +| PYRAMID_LIST | **`storage=(FILE\|S3)`**, *`depth=`*, **`size=x`**, *`levels=[, ...]`* | HEATMAP | **`bbox=,,, or area=`**, **`dimensions=x or level=`** | Génère une carte de chaleur des dalles à partir des lignes d'un fichier liste de pyramide | Aires prédéfinies pour une carte de chaleur : * `EPSG:3857` * `FXX` (France métropolitaine) +* `EPSG:2154` + * `FXX` (France métropolitaine) +* `IGNF:LAMB93` + * `FXX` (France métropolitaine) Exemple (GETTILE_PARAMS -> HEATMAP) : @@ -187,6 +193,10 @@ Exemple (GETTILE_PARAMS -> SLAB) pour une tuile : `echo "/?TILEMATRIXSET=LAMB93_5cm&TILEMATRIX=18&TILECOL=4158&TILEROW=27790" | tmsizer --tms LAMB93_5cm -if GETTILE_PARAMS -of SLAB -oo storage=S3 -oo size=16x16` +Exemple (PYRAMID_LIST -> HEATMAP) pour un fichier liste (l'écart entre le niveau en entrée 22 et le niveau de calage en sortie 18 permet d'avoir un pixel pour une dalle avec 16x16 tuiles par dalle. Une tuile de niveau 18 couvre la même zone qu'une dalle de niveau 22) : + +`tmsizer -i pyramid.list --tms 2154_5cm -if PYRAMID_LIST -of HEATMAP -io storage=S3 -io size=16x16 -io levels=22 -oo area=FXX -oo level=18 -o heatmap.tif --progress` + ## Compiler la suite d'outils diff --git a/README.pypi.md b/README.pypi.md index d5ec98a..d7515de 100644 --- a/README.pypi.md +++ b/README.pypi.md @@ -165,13 +165,20 @@ Availables conversions (mandatory options in bold, optionnal options in italic) | Input format | Input options | Output format | Output options | Description | |----------------|---------------------------------------------------|----------------|---------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------| | GETTILE_PARAMS | *`levels=[, ...]`*,*`layers=[, ...]`* | COUNT | | Count the GetTiles requests using the pivot TMS and optionnally the provided level and layer | +| GETTILE_PARAMS | | SLAB | **`size=x`**, **`storage=(FILE\|S3)`** | Generate slab's informations for each requested tile (indices and storage path) | | GETTILE_PARAMS | *`levels=[, ...]`*,*`layers=[, ...]`* | HEATMAP | **`bbox=,,, or area=`**, **`dimensions=x or level=`** | Create an heat map of requested tiles on the provided area, optionnaly filtering with provided level and layer | | GEOMETRY | **`format=`**,**`level=`** | GETTILE_PARAMS | | Generate GetTile query parameters for tiles intersecting input geometries for the provided level | +| PYRAMID_LIST | **`storage=(FILE\|S3)`**, `depth=` | SLAB | | Generate slab's informations from pyramid's list lines | +| PYRAMID_LIST | **`storage=(FILE\|S3)`**, *`depth=`*, **`size=x`**, *`levels=[, ...]`* | HEATMAP | **`bbox=,,, or area=`**, **`dimensions=x or level=`** | Generate slabs' heatmap from pyramid's list lines | Available areas for a heatmap : * `EPSG:3857` * `FXX` (European France) +* `EPSG:2154` + * `FXX` (European France) +* `IGNF:LAMB93` + * `FXX` (European France) Example (GETTILE_PARAMS -> HEATMAP) : @@ -180,3 +187,11 @@ Example (GETTILE_PARAMS -> HEATMAP) : Example (GETTILE_PARAMS -> HEATMAP) with predefined area and pixel-level superposition: `tmsizer -i logs.txt --tms PM -if GETTILE_PARAMS -of HEATMAP -oo area=FXX -oo level=15 -o heatmap.tif` + +Exemple (GETTILE_PARAMS -> SLAB) for a tile : + +`echo "/?TILEMATRIXSET=LAMB93_5cm&TILEMATRIX=18&TILECOL=4158&TILEROW=27790" | tmsizer --tms LAMB93_5cm -if GETTILE_PARAMS -of SLAB -oo storage=S3 -oo size=16x16` + +Exemple (PYRAMID_LIST -> HEATMAP) for a full pyramid's list : + +`tmsizer -i pyramid.list --tms 2154_5cm -if PYRAMID_LIST -of HEATMAP -io storage=S3 -io size=16x16 -io levels=22 -oo area=FXX -oo level=18 -o heatmap.tif --progress` diff --git a/src/rok4_tools/tmsizer.py b/src/rok4_tools/tmsizer.py index ff29d8a..0120129 100644 --- a/src/rok4_tools/tmsizer.py +++ b/src/rok4_tools/tmsizer.py @@ -186,7 +186,9 @@ def load_conversion() -> None: To process data from input to output format, several processors can be chained * GETTILE_PARAMS -> COUNT : Gettile2tileindexProcessor -> CountProcessor - * GETTILE_PARAMS -> SLAB : Gettile2tileindexProcessor -> SlabProcessor + * GETTILE_PARAMS -> SLAB : Gettile2tileindexProcessor -> Tileindex2slabProcessor + * PYRAMID_LIST -> SLAB : Slablist2slabProcessor + * PYRAMID_LIST -> HEATMAP : Slablist2slabProcessor -> Slab2pointProcessor -> HeatmapProcessor * GETTILE_PARAMS -> HEATMAP : Gettile2tileindexProcessor -> Tileindex2pointProcessor -> HeatmapProcessor * GEOMETRY -> GETTILE_PARAMS : Geometry2tileindexProcessor -> Tileindex2gettileProcessor """ @@ -203,6 +205,17 @@ def load_conversion() -> None: elif args.output_format == "SLAB": conversion_processor = Tileindex2slabProcessor(tp, **output_options) + elif args.input_format == "PYRAMID_LIST": + tp = Slablist2slabProcessor(reader_processor, **input_options) + + if args.output_format == "SLAB": + conversion_processor = tp + + if args.output_format == "HEATMAP": + conversion_processor = HeatmapProcessor( + Slab2pointProcessor(tp, **input_options), **output_options + ) + elif args.input_format == "GEOMETRY": tp = Geometry2tileindexProcessor(reader_processor, **input_options) diff --git a/src/rok4_tools/tmsizer_utils/processors/map.py b/src/rok4_tools/tmsizer_utils/processors/map.py index 9d8b8c3..abbd81d 100644 --- a/src/rok4_tools/tmsizer_utils/processors/map.py +++ b/src/rok4_tools/tmsizer_utils/processors/map.py @@ -20,7 +20,7 @@ gdal.UseExceptions() from rok4.enums import StorageType -from rok4.pyramid import b36_path_encode +from rok4.pyramid import b36_path_decode, b36_path_encode from rok4.utils import bbox_to_geometry from rok4_tools.tmsizer_utils.processors.processor import Processor @@ -134,10 +134,221 @@ def __str__(self) -> str: return f"Gettile2tileindexProcessor : {self._processed} {self.__input.format} items processed, extracting tile's indices" +class Slablist2slabProcessor(Processor): + """Processor generating slab informations (indices and path) from pyramid's list items + + Accepted input format is "PYRAMID_LIST" and output format is "SLAB" + + Attributes: + __input (Processor): Processor from which data is read + __storage_type (StorageType): Storage type for slab's path + __storage_depth (int): Storage depth for slab's path for FILE storage + """ + + input_formats_allowed = ["PYRAMID_LIST"] + + def __init__(self, input: Processor, **options): + """Constructor method + + Args: + input (Processor): Processor from which data is read + **storage (str): Storage type for slab's path + + Raises: + ValueError: Input format is not allowed + """ + + if input.format not in self.input_formats_allowed: + raise ValueError( + f"Input format {input.format} is not handled for Slablist2slabProcessor : allowed formats are {self.input_formats_allowed}" + ) + + super().__init__("SLAB") + + self.__input = input + + try: + self.__storage_type = StorageType[options["storage"]] + + except KeyError: + raise KeyError( + "Option storage is required to generate slab infos from pyramid's list items and have to be a valid storage type (FILE or S3)" + ) + + if self.__storage_type == StorageType.FILE: + try: + self.__storage_depth = int(options["depth"]) + + except KeyError: + raise KeyError( + "Option depth is required to generate slab infos from pyramid's list items for FILE storage" + ) + + def process(self) -> Iterator[Tuple[str, int, int, str]]: + """Read a pyramid's list item from the input processor and generate slab's infos (path and indices) + + Examples: + + Get slab informations + + from rok4_tools.tmsizer_utils.processors.map import Tileindex2slabProcessor + + try: + # Creation of Processor source_processor with format PYRAMID_LIST + processor = Slablist2slabProcessor(source_processor, storage="FILE", depth=2) + for item in processor.process(): + slab_infos = item + + except Exception as e: + print("{e}") + + Yields: + Iterator[Tuple[str, int, int, str]]: Slab index and path (level, col, row, path) + """ + + if self.__input.format == "PYRAMID_LIST": + # Lecture du header + roots = {} + header = True + for item in self.__input.process(): + if header: + if item == "#": + header = False + else: + root_id, root_path = item.split("=", 1) + roots[root_id] = root_path + continue + + self._processed += 1 + + parts = item.split(" ", 1) + slab_path = parts[0] + + if self.__storage_type == StorageType.FILE: + parts = slab_path.split("/") + parts[0] = roots[parts[0]] + + # Le partie du chemin qui contient la colonne et ligne de la dalle est à la fin, en fonction de la profondeur choisie + # depth = 2 -> on doit utiliser les 3 dernières parties pour la conversion + column, row = b36_path_decode("/".join(parts[-(self.__storage_depth + 1) :])) + level = parts[-(self.__storage_depth + 2)] + + yield level, column, row, "/".join(parts) + else: + root, name = slab_path.split("/") + root = roots[root] + + parts = name.split("_") + column = parts[-2] + row = parts[-1] + level = parts[-3] + + yield level, int(column), int(row), f"{root}/{'_'.join(parts)}" + + def __str__(self) -> str: + return f"Slablist2slabindexProcessor : {self._processed} {self.__input.format} items processed, generating slab's indices and path" + + +class Slab2pointProcessor(Processor): + """Processor generating the slab's center coordinates from slab infos + + Accepted input format is "SLAB" and output format is "POINT" + + Attributes: + __input (Processor): Processor from which data is read + __slab_size (Tuple[int, int]): Slab size, in tiles, widthwise and heightwise + __levels (List[str], optional): Tile matrix identifier(s) to filter data + """ + + input_formats_allowed = ["SLAB"] + + def __init__(self, input: Processor, **options): + """Constructor method + + Args: + input (Processor): Processor from which data is read + **size (str): Slab size, in tiles. Format "x" + **levels (str, optional): Tile matrix identifier(s) to filter data + + Raises: + ValueError: Input format is not allowed + ValueError: Provided level is not in the pivot TMS + """ + + if input.format not in self.input_formats_allowed: + raise ValueError( + f"Input format {input.format} is not handled for Slab2pointProcessor : allowed formats are {self.input_formats_allowed}" + ) + + super().__init__("POINT") + + try: + self.__slab_size = [int(c) for c in options["size"].split("x")] + self.__slab_size = tuple(self.__slab_size) + + except KeyError as e: + raise KeyError(f"Option {e} is required to generate slab infos from tile indices") + + if "levels" in options.keys(): + self.__levels = options["levels"].split(",") + for l in self.__levels: + if self.tms.get_level(l) is None: + raise ValueError(f"The provided level '{l}' is not in the TMS") + else: + self.__levels = None + + self.__input = input + + def process(self) -> Iterator[Tuple[float, float]]: + """Read a tile index from the input processor and generate the tile's center coordinates + + Examples: + + Get slab's center coordinates + + from rok4_tools.tmsizer_utils.processors.map import Slab2pointProcessor + + try: + # Creation of Processor source_processor with format SLAB + processor = Slab2pointProcessor(source_processor, size="16x16") + for item in processor.process(): + (x, y) = item + + except Exception as e: + print("{e}") + + Yields: + Iterator[Tuple[float, float]]: point coordinates (x,y) + """ + + if self.__input.format == "SLAB": + for item in self.__input.process(): + self._processed += 1 + + (level, col, row, path) = item + + if self.__levels is not None and level not in self.__levels: + continue + + try: + bb = self.tms.get_level(level).slab_to_bbox(col, row, self.__slab_size) + + x_center = bb[0] + (bb[2] - bb[0]) / 2 + y_center = bb[1] + (bb[3] - bb[1]) / 2 + + yield (x_center, y_center) + except Exception: + # Le niveau n'est pas valide, on passe simplement + pass + + def __str__(self) -> str: + return f"Slab2pointProcessor : {self._processed} {self.__input.format} items processed, extracting slab's center coordinates" + + class Tileindex2slabProcessor(Processor): - """Processor generating WMTS GetTile query parameters from tile index + """Processor generating slab's informations from tile index - Accepted input format is "TILE_INDEX" and output format is "GETTILE_PARAMS" + Accepted input format is "TILE_INDEX" and output format is "SLAB" Attributes: __input (Processor): Processor from which data is read @@ -194,7 +405,7 @@ def process(self) -> Iterator[Tuple[str, int, int, str]]: try: # Creation of Processor source_processor with format TILE_INDEX - processor = Tileindex2slabProcessor(source_processor) + processor = Tileindex2slabProcessor(source_processor, storage="S3", size="8x8") for item in processor.process(): slab_infos = item @@ -222,7 +433,7 @@ def process(self) -> Iterator[Tuple[str, int, int, str]]: yield (level, slab_col, slab_row, slab_path) def __str__(self) -> str: - return f"Tileindex2gettileProcessor : {self._processed} {self.__input.format} items processed, generating GetTile's query parameters" + return f"Tileindex2slabProcessor : {self._processed} {self.__input.format} items processed, generating slab's indices and path" class Tileindex2gettileProcessor(Processor): diff --git a/src/rok4_tools/tmsizer_utils/processors/reduce.py b/src/rok4_tools/tmsizer_utils/processors/reduce.py index c17a06f..df40cbe 100644 --- a/src/rok4_tools/tmsizer_utils/processors/reduce.py +++ b/src/rok4_tools/tmsizer_utils/processors/reduce.py @@ -86,7 +86,11 @@ class HeatmapProcessor(Processor): input_formats_allowed = ["POINT"] - areas = {"EPSG:3857": {"FXX": [-649498, 5048729, 1173394, 6661417]}} + areas = { + "EPSG:3857": {"FXX": [-649498, 5048729, 1173394, 6661417]}, + "EPSG:2154": {"FXX": [28133, 5942256, 1322512, 7210428]}, + "IGNF:LAMB93": {"FXX": [28133, 5942256, 1322512, 7210428]}, + } def __init__(self, input: Processor, **options): """Constructor method From 4aabc4c5186e4ce732d2ea124f1f389b383f5729 Mon Sep 17 00:00:00 2001 From: Theo Satabin Date: Mon, 3 Nov 2025 17:46:50 +0100 Subject: [PATCH 2/2] Passage au formta keepachangelog --- CHANGELOG.md | 70 ++++++++++++++++++++----------------------------- CONTRIBUTING.md | 16 +++++------ 2 files changed, 35 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d29775..c6602ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,88 +1,74 @@ # Changelog - Tous les changements sont consignés dans ce fichier. Le format est basé sur [Keep a Changelog](https://keepachangelog.com/) et ce projet respecte le [Semantic Versioning](https://semver.org/). ## [Unreleased] - ### Added - -* Outil TMSIZER : ajout de la conversion GETTILE_PARAMS -> SLAB, pour avoir les informations sur la dalle contenant la tuile (indices et chemin de stockage) - +- Outil TMSIZER : + * ajout de la conversion GETTILE_PARAMS -> SLAB, pour avoir les informations sur la dalle contenant la tuile (indices et chemin de stockage) + * ajout des conversions PYRAMID_LIST -> SLAB et PYRAMID_LIST -> HEATMAP pour avoir des informations de dalle ou une carte de chaleur à partir du fichier liste d'une pyramide ### Changed -### Deprecated -### Removed -### Fixed -### Security +- Refonte du CHANGELOG au format [Keep a Changelog](https://keepachangelog.com/) ## [1.5.2] - 2024-11-06 - ### Added - -* Outil TMSIZER : possibilité de préciser une aire prédéinie à la place de la bbox et un niveau à la place des dimensions pour l'écriture d'une heatmap (une tuile du niveau correspondra à un pixel) +- Outil TMSIZER : possibilité de préciser une aire prédéinie à la place de la bbox et un niveau à la place des dimensions pour l'écriture d'une heatmap (une tuile du niveau correspondra à un pixel) ## [1.5.1] - 2024-09-18 - ### Added - -* Outil TMSIZER : ajout d'une option pour filtrer sur la couche pour le format en entrée GETTILE_PARAMS : fourniture d'une liste de couches avec l'option `layers` +- Outil TMSIZER : ajout d'une option pour filtrer sur la couche pour le format en entrée GETTILE_PARAMS : fourniture d'une liste de couches avec l'option `layers` ### Changed - -* Outil TMSIZER : modification de l'option pour filtrer sur le niveau pour le format en entrée GETTILE_PARAMS : fourniture d'une liste de niveaux et l'option `level` devient `levels` - +- Outil TMSIZER : modification de l'option pour filtrer sur le niveau pour le format en entrée GETTILE_PARAMS : fourniture d'une liste de niveaux et l'option `level` devient `levels` ## [1.5.0] - 2024-04-30 - ### Added - -* Outil TMSIZER : convertit des informations en d'autres en s'appuyant sur un TMS pivot. Conversions implémentées : +- Outil TMSIZER : convertit des informations en d'autres en s'appuyant sur un TMS pivot. Conversions implémentées : * GETTILE_PARAMS -> HEATMAP * GETTILE_PARAMS -> COUNT * GEOMETRY -> GETTILE_PARAMS -* Outil PYROLYSE : compile des statistiques (nombre de dalles / tuile, taille, temps d'accès) sur une pyramide de données, au global et par niveau +- Outil PYROLYSE : compile des statistiques (nombre de dalles / tuile, taille, temps d'accès) sur une pyramide de données, au global et par niveau ## [1.3.2] - 2024-01-31 - ### Added - -* Outil JOINCACHE génèrent une pyramide à partir d'autres pyramides raster compatibles. Fonctionne en plusieurs modes : +- Outil JOINCACHE génèrent une pyramide à partir d'autres pyramides raster compatibles. Fonctionne en plusieurs modes : * 3 pour la génération : master, agent et finisher * 2 pour l'aide : example et check -* Création de la classe "source" pour charger des sources de données +- Création de la classe "source" pour charger des sources de données ### Changed - -* Division de l'outil PYR2PYR en un fichier principal (pyr2pyr.py) et des fichier par rôles (pyr2pyr_utils/agent.py, pyr2pyr_utils.master.py, pyr2pyr_utils.finisher.py) -* Gestion des documentations des différentes versions avec l'outil [mike](https://github.com/jimporter/mike) +- Division de l'outil PYR2PYR en un fichier principal (pyr2pyr.py) et des fichier par rôles (pyr2pyr_utils/agent.py, pyr2pyr_utils.master.py, pyr2pyr_utils.finisher.py) +- Gestion des documentations des différentes versions avec l'outil [mike](https://github.com/jimporter/mike) ## [1.2.1] - 2023-03-10 - ### Added - -* Outil MAKE-LAYER : génère un descripteur de couche compatible avec le serveur à partir des pyramides de données à utiliser -* Ajout de la publication PyPI dans la CI GitHub +- Outil MAKE-LAYER : génère un descripteur de couche compatible avec le serveur à partir des pyramides de données à utiliser +- Ajout de la publication PyPI dans la CI GitHub ### Changed - -* Renommage pour plus de cohérence avec les pratiques : +- Renommage pour plus de cohérence avec les pratiques : * Le module rok4 est renommé : rok4lib -> rok4 * Le module d'outil est renommé : rok4tools -> rok4_tools. Le package a le nom rok4-tools * Le script make-layer.py -> make_layer.py -* Passage de la configuration du projet dans le fichier `pyproject.toml` +- Passage de la configuration du projet dans le fichier `pyproject.toml` ## [1.1.0] - 2023-01-13 - ### Changed - -* Outil PYR2PYR : +- Outil PYR2PYR : * Les pyramides source et destination peuvent être sur des clusters S3 différents. Ils sont précisés lors de la recopie des dalles. Pour préciser le cluster dans le chemin vers le descripteur de la pyramide source (ou l'emplacement de la pyramide destination), il suffit de suffixer le nom du bucket avec `@{hôte du cluster}`. ## [1.0.0] - 2022-11-28 - ### Added - -* Outil PYR2PYR de copie de pyramide : copie d'une pyramide d'un stockage à une autre. Contrôle les signatures MD5 si présente dans le fichier liste. Fonctionne en plusieurs modes : +- Outil PYR2PYR de copie de pyramide : copie d'une pyramide d'un stockage à une autre. Contrôle les signatures MD5 si présente dans le fichier liste. Fonctionne en plusieurs modes : * 3 pour la recopie : master, agent et finisher * 2 pour l'aide : example et check + +[Unreleased]: https://github.com/rok4/pytools/compare/v1.5.2...HEAD +[1.5.2]: https://github.com/rok4/pytools/compare/v1.5.1...v1.5.2 +[1.5.1]: https://github.com/rok4/pytools/compare/v1.5.0...v1.5.1 +[1.5.0]: https://github.com/rok4/pytools/compare/v1.3.2...v1.5.0 +[1.3.2]: https://github.com/rok4/pytools/compare/v1.2.1...v1.3.2 +[1.2.1]: https://github.com/rok4/pytools/compare/v1.1.0...v1.2.1 +[1.1.0]: https://github.com/rok4/pytools/compare/v1.0.0...v1.1.0 +[1.0.0]: https://github.com/rok4/pytools/releases/tag/v1.0.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 235d04a..e7d6c89 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,32 +15,30 @@ Voir le fichier de configuration correspondant : `.pre-commit-config.yaml`. ## Pull request -Le titre de la PR est utilisé pour constituer automatiquement les notes de release. Vous pouvez préciser en commentaire de votre PR des détails qui seront ajoutés dans le fichier `CHANGELOG.md` par les mainteneurs du projet. - -Le formalisme du changelog est le suivant, en markdown : +Complétez le fichier `CHANGELOG.md`, dans la partie `[Unreleased]`, en précisant les modifications fonctionnelles apportées. Celles ci seront utilisées pour rédiger le message de release sur GitHub. Le format est basé sur [Keep a Changelog](https://keepachangelog.com/). Les sections sont les suivantes : ```md -### [Added] +### Added Liste de nouvelles fonctionnalités. -### [Changed] +### Changed Liste de fonctionnalités existantes modifiées. -### [Deprecated] +### Deprecated Liste de fonctionnalités dépréciées. -### [Removed] +### Removed Liste de foncitonnalités retirées. -### [Fixed] +### Fixed Liste de corrections fonctionnelles. -### [Security] +### Security Liste de corrections de sécurité. ```