From b8c8dde0eed08ba158357bbb0c22807ef1ac1f6e Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Mon, 16 Dec 2024 15:29:15 +0100 Subject: [PATCH 01/25] correct typo --- frontend/src/assets/i18n/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/assets/i18n/fr.json b/frontend/src/assets/i18n/fr.json index a437e1745a..88b2f5b44d 100644 --- a/frontend/src/assets/i18n/fr.json +++ b/frontend/src/assets/i18n/fr.json @@ -296,7 +296,7 @@ "SourceFieldsAllMapped": "L'ensemble des {{ sourceFieldsLength }} champs du fichier d’import ont été associés à un champs cible.", "SourceFieldsUnmapped": "{{ unmappedFieldsLength }} champs du fichier d’import ne sont actuellement associés à aucun champs cible et seront donc ignorés.", "SaveMapping": "Enregistrement du modèle", - "MappingCreate?": "Souhaitez sauvegarder vos correspondances dans un modèle pour les réutiliser lors d’un futur import ?", + "MappingCreate?": "Souhaitez-vous sauvegarder vos correspondances dans un modèle pour les réutiliser lors d’un futur import ?", "MappingChanged?": "Le modèle de correspondance a été modifié ; souhaitez-vous mettre à jour le modèle existant ou créer un nouveau modèle ?", "MappingName": "Nom du modèle", "MappingNameWarning": "Un nom doit être renseigné pour pouvoir créer un modèle", From 8aa6ff6023e1b6b4e68241a0fedcf74740732026 Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Tue, 17 Dec 2024 10:53:21 +0100 Subject: [PATCH 02/25] feat(mapping,import): enable save of public mapping when user got U>3 + TODO -> check if user is owner --- backend/geonature/core/imports/schemas.py | 2 ++ .../fields-mapping-step.component.ts | 13 +++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/backend/geonature/core/imports/schemas.py b/backend/geonature/core/imports/schemas.py index 7035f2e815..bdedb79bd1 100644 --- a/backend/geonature/core/imports/schemas.py +++ b/backend/geonature/core/imports/schemas.py @@ -4,6 +4,7 @@ from utils_flask_sqla.schema import SmartRelationshipsMixin from geonature.core.imports.models import Destination, FieldMapping, MappingTemplate +from pypnusershub.schemas import UserSchema from geonature.core.gn_commons.schemas import ModuleSchema from marshmallow import fields @@ -27,3 +28,4 @@ class Meta: cruved = fields.Dict() values = fields.Dict() + owners = fields.List(fields.Nested(UserSchema(only=["identifiant"]))) diff --git a/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts b/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts index 918521e00a..c09532f1b2 100644 --- a/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts +++ b/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts @@ -95,11 +95,13 @@ export class FieldsMappingStepComponent implements OnInit { return; } let mappingValue = this._fieldMappingService.currentFieldMapping.value; - if ( - this._fieldMappingService.mappingFormGroup.dirty && - (this.cruved.C || (mappingValue && mappingValue.cruved.U && !mappingValue.public)) // - ) { - if (mappingValue && !mappingValue.public) { + const update_mapping_right = + this._cruvedStore.cruved.IMPORT.module_objects.MAPPING.cruved.U > 2; + if (this._fieldMappingService.mappingFormGroup.dirty && mappingValue && this.cruved.C) { + if (mappingValue.public && update_mapping_right) { + this.updateAvailable = true; + this.modalCreateMappingForm.setValue(mappingValue.label); + } else if (!mappingValue.public) { this.updateAvailable = true; this.modalCreateMappingForm.setValue(mappingValue.label); } else { @@ -108,7 +110,6 @@ export class FieldsMappingStepComponent implements OnInit { } this._modalService.open(this.saveMappingModal, { size: 'lg' }); } else { - // this.spinner = true; this.processNextStep(); } } From 9bacad9d597f55f6d9be441ebcb26881634d78ad Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Tue, 17 Dec 2024 11:10:28 +0100 Subject: [PATCH 03/25] feat(import, fieldmapping): now owner of public mapping can edit --- .../fields-mapping-step.component.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts b/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts index c09532f1b2..bb71f8713e 100644 --- a/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts +++ b/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts @@ -17,6 +17,7 @@ import { } from '@geonature/modules/imports/models/mapping.model'; import { ConfigService } from '@geonature/services/config.service'; import { FormControl } from '@angular/forms'; +import { AuthService } from '@geonature/components/auth/auth.service'; @Component({ selector: 'pnx-fields-mapping-step', @@ -41,7 +42,8 @@ export class FieldsMappingStepComponent implements OnInit { private _cruvedStore: CruvedStoreService, private _importDataService: ImportDataService, private _modalService: NgbModal, - private _configService: ConfigService + private _configService: ConfigService, + private _authService: AuthService ) {} ngOnInit() { @@ -94,11 +96,19 @@ export class FieldsMappingStepComponent implements OnInit { if (!this._fieldMappingService.mappingFormGroup?.valid) { return; } + + // Mapping stored data let mappingValue = this._fieldMappingService.currentFieldMapping.value; - const update_mapping_right = - this._cruvedStore.cruved.IMPORT.module_objects.MAPPING.cruved.U > 2; + // is mapping update right for the current user is at admin level + const updateMappingRight = this._cruvedStore.cruved.IMPORT.module_objects.MAPPING.cruved.U > 2; + // + const currentUser = this._authService.getCurrentUser(); + const intersectMappingOwnerUser = mappingValue['owners'].filter( + (x) => x.identifiant == currentUser.user_login + ); + if (this._fieldMappingService.mappingFormGroup.dirty && mappingValue && this.cruved.C) { - if (mappingValue.public && update_mapping_right) { + if (mappingValue.public && (updateMappingRight || intersectMappingOwnerUser)) { this.updateAvailable = true; this.modalCreateMappingForm.setValue(mappingValue.label); } else if (!mappingValue.public) { From 07f46770743a7a78827baf2b7aa7af6b89f9f76f Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Tue, 17 Dec 2024 14:21:28 +0100 Subject: [PATCH 04/25] feat(install): add new grid layer to database population script --- install/03b_populate_db.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/install/03b_populate_db.sh b/install/03b_populate_db.sh index c0495f6168..f65a4d21d4 100755 --- a/install/03b_populate_db.sh +++ b/install/03b_populate_db.sh @@ -38,6 +38,22 @@ then geonature db upgrade ref_geo_inpn_grids_10@head fi +if [ "$install_grid_layer" = true ] || [ "$install_grid_layer_2" = true ]; +then + geonature db upgrade ref_geo_inpn_grids_2@head +fi + +if [ "$install_grid_layer" = true ] || [ "$install_grid_layer_20" = true ]; +then + geonature db upgrade ref_geo_inpn_grids_20@head +fi + +if [ "$install_grid_layer" = true ] || [ "$install_grid_layer_50" = true ]; +then + geonature db upgrade ref_geo_inpn_grids_50@head +fi + + geonature db exec "DO 'BEGIN ASSERT EXISTS (SELECT 1 FROM gn_sensitivity.t_sensitivity_rules); END'" 2>/dev/null \ || if [ "$install_ref_sensitivity" = true ]; then From 1abef70fd64f783103371b9adaf3f4348058de5f Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Tue, 17 Dec 2024 14:56:27 +0100 Subject: [PATCH 05/25] fix(import,upload): fix autofill of the dataset form with query params --- .../upload-file-step/upload-file-step.component.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/src/app/modules/imports/components/import_process/upload-file-step/upload-file-step.component.ts b/frontend/src/app/modules/imports/components/import_process/upload-file-step/upload-file-step.component.ts index d34403894e..9cb702b5b9 100644 --- a/frontend/src/app/modules/imports/components/import_process/upload-file-step/upload-file-step.component.ts +++ b/frontend/src/app/modules/imports/components/import_process/upload-file-step/upload-file-step.component.ts @@ -50,9 +50,15 @@ export class UploadFileStepComponent implements OnInit { this.setupDatasetSelect(); this.step = this.route.snapshot.data.step; this.importData = this.importProcessService.getImportData(); + if (this.importData) { this.uploadForm.patchValue({ dataset: this.importData.id_dataset }); this.fileName = this.importData.full_file_name; + } else { + const idDatasetQueryParams = this.route.snapshot.queryParamMap.get('datasetId'); + if (idDatasetQueryParams) { + this.uploadForm.patchValue({ dataset: parseInt(idDatasetQueryParams) }); + } } } From ccde99afe63604aec13eeed5bfbf65bdad039b1c Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Tue, 17 Dec 2024 17:06:48 +0100 Subject: [PATCH 06/25] feat(import, mapping) : update public mapping : (owner + u>0) ou (u>3) --- .../fields-mapping-step.component.ts | 14 ++++++++++---- .../import_report/import_report.component.html | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts b/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts index bb71f8713e..0b418411c8 100644 --- a/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts +++ b/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts @@ -100,15 +100,21 @@ export class FieldsMappingStepComponent implements OnInit { // Mapping stored data let mappingValue = this._fieldMappingService.currentFieldMapping.value; // is mapping update right for the current user is at admin level - const updateMappingRight = this._cruvedStore.cruved.IMPORT.module_objects.MAPPING.cruved.U > 2; + const hasAdminUpdateMappingRight = + this._cruvedStore.cruved.IMPORT.module_objects.MAPPING.cruved.U > 2; + const hasOwnMappingUpdateRight = + this._cruvedStore.cruved.IMPORT.module_objects.MAPPING.cruved.U > 0; // const currentUser = this._authService.getCurrentUser(); - const intersectMappingOwnerUser = mappingValue['owners'].filter( - (x) => x.identifiant == currentUser.user_login + const intersectMappingOwnerUser = mappingValue['owners'].filter((x) => + x.identifiant == currentUser.user_login ? mappingValue['owners'] : false ); if (this._fieldMappingService.mappingFormGroup.dirty && mappingValue && this.cruved.C) { - if (mappingValue.public && (updateMappingRight || intersectMappingOwnerUser)) { + if ( + mappingValue.public && + (hasAdminUpdateMappingRight || (hasOwnMappingUpdateRight && intersectMappingOwnerUser)) + ) { this.updateAvailable = true; this.modalCreateMappingForm.setValue(mappingValue.label); } else if (!mappingValue.public) { diff --git a/frontend/src/app/modules/imports/components/import_report/import_report.component.html b/frontend/src/app/modules/imports/components/import_report/import_report.component.html index 43b87d6392..04c3d44d32 100644 --- a/frontend/src/app/modules/imports/components/import_report/import_report.component.html +++ b/frontend/src/app/modules/imports/components/import_report/import_report.component.html @@ -12,7 +12,7 @@
- Rapport d'import: + Rapport d'import : {{ importData?.id_import }}
Date: Tue, 17 Dec 2024 17:18:04 +0100 Subject: [PATCH 07/25] fix backend test --- backend/geonature/tests/imports/jsonschema_definitions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/geonature/tests/imports/jsonschema_definitions.py b/backend/geonature/tests/imports/jsonschema_definitions.py index 42a94a4520..a220b61bfa 100644 --- a/backend/geonature/tests/imports/jsonschema_definitions.py +++ b/backend/geonature/tests/imports/jsonschema_definitions.py @@ -307,6 +307,9 @@ "values": { "type": ["null", "object"], }, + "owners": { + "type": ["null", "array"], + }, }, "minProperties": 7, "additionalProperties": False, From 58a129ae49667990b48ad75b8eb4ff78f2420633 Mon Sep 17 00:00:00 2001 From: Pierre-Narcisi Date: Wed, 18 Dec 2024 10:22:21 +0100 Subject: [PATCH 08/25] fix(admin) import mapping --- backend/geonature/core/imports/admin.py | 36 +++++++++--------------- backend/geonature/core/imports/models.py | 23 +++++++++++---- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/backend/geonature/core/imports/admin.py b/backend/geonature/core/imports/admin.py index 5f48485c8a..cf4dd0844e 100644 --- a/backend/geonature/core/imports/admin.py +++ b/backend/geonature/core/imports/admin.py @@ -14,7 +14,7 @@ from pypnnomenclature.models import TNomenclatures -from geonature.core.imports.models import FieldMapping, ContentMapping +from geonature.core.imports.models import Destination, FieldMapping, ContentMapping from flask_admin.contrib.sqla.form import AdminModelConverter from flask_admin.model.form import converts @@ -25,35 +25,21 @@ class MappingView(CruvedProtectedMixin, ModelView): object_code = "MAPPING" can_view_details = True - column_list = ( - "label", - "active", - "public", - ) + column_list = ("label", "active", "public", "destination") column_searchable_list = ("label",) column_filters = ( "active", "public", ) - form_columns = ( - "label", - "active", - "public", - "owners", - "values", - ) - column_details_list = ( - "label", - "active", - "public", - "owners", - "values", - ) + form_columns = ("label", "active", "public", "owners", "values", "destination") + column_details_list = ("label", "active", "public", "owners", "values", "destination") column_labels = { "active": "Actif", "owners": "Propriétaires", "values": "Correspondances", + "destination": "Destinations", } + column_formatters = {"destination": lambda v, c, m, p: m.destination.label} column_export_list = ( "label", "values", @@ -61,15 +47,21 @@ class MappingView(CruvedProtectedMixin, ModelView): def FieldMappingValuesValidator(form, field): + destination = db.session.execute( + db.select(Destination).where(Destination.id_destination == form.destination.raw_data[0]) + ).scalar_one_or_none() try: - FieldMapping.validate_values(field.data) + FieldMapping.validate_values(field.data, destination) except ValueError as e: raise StopValidation(*e.args) def ContentMappingValuesValidator(form, field): + destination = db.session.execute( + db.select(Destination).where(Destination.id_destination == form.destination.raw_data[0]) + ).scalar_one_or_none() try: - ContentMapping.validate_values(field.data) + ContentMapping.validate_values(field.data, destination) except ValueError as e: raise StopValidation(*e.args) diff --git a/backend/geonature/core/imports/models.py b/backend/geonature/core/imports/models.py index 958b359a9d..cbab0bc599 100644 --- a/backend/geonature/core/imports/models.py +++ b/backend/geonature/core/imports/models.py @@ -219,6 +219,9 @@ def has_instance_permission(self, user: Optional[User] = None, action_code: str ] return max_scope > 0 + def __repr__(self): + return self.label + @serializable class BibThemes(db.Model): @@ -520,7 +523,7 @@ class MappingTemplate(db.Model): __table_args__ = {"schema": "gn_imports"} id = db.Column(db.Integer, primary_key=True) - id_destination = db.Column(db.Integer, ForeignKey(Destination.id_destination)) + id_destination = db.Column(db.Integer, ForeignKey(Destination.id_destination), nullable=False) destination = relationship(Destination) label = db.Column(db.Unicode(255), nullable=False) type = db.Column(db.Unicode(10), nullable=False) @@ -667,7 +670,7 @@ class FieldMapping(MappingTemplate): } @staticmethod - def validate_values(field_mapping_json): + def validate_values(field_mapping_json, destination=None): """ Validate the field mapping values returned by the client form. @@ -689,8 +692,13 @@ def validate_values(field_mapping_json): "optional_conditions", "mandatory_conditions", ] + (g.destination if (destination is None) else destination) entities_for_destination: List[Entity] = ( - Entity.query.filter_by(destination=g.destination).order_by(sa.desc(Entity.order)).all() + Entity.query.filter_by( + destination=(g.destination if (destination is None) else destination) + ) + .order_by(sa.desc(Entity.order)) + .all() ) fields = [] for entity in entities_for_destination: @@ -717,7 +725,9 @@ def validate_values(field_mapping_json): entity, columns=bib_fields_col, optional_where_clause=sa.and_( - BibFields.destination == g.destination, BibFields.display == True + BibFields.destination + == (g.destination if (destination is None) else destination), + BibFields.display == True, ), ) ) @@ -771,10 +781,11 @@ class ContentMapping(MappingTemplate): } @staticmethod - def validate_values(values): + def validate_values(values, destination=None): nomenclature_fields = ( BibFields.query.filter( - BibFields.destination == g.destination, BibFields.nomenclature_type != None + BibFields.destination == (g.destination if (destination is None) else destination), + BibFields.nomenclature_type != None, ) .options( joinedload(BibFields.nomenclature_type).joinedload( From 36e93ba987878a2b5a71955e7d29d9fba27f602d Mon Sep 17 00:00:00 2001 From: Pierre-Narcisi Date: Mon, 6 Jan 2025 11:34:19 +0100 Subject: [PATCH 09/25] fix(import, mapping) fix checkbox and import step --- .../fields-mapping-step/fields-mapping-step.component.ts | 6 +++--- .../imports/services/mappings/field-mapping.service.ts | 8 ++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts b/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts index 0b418411c8..5ccc50a6a7 100644 --- a/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts +++ b/frontend/src/app/modules/imports/components/import_process/fields-mapping-step/fields-mapping-step.component.ts @@ -106,11 +106,11 @@ export class FieldsMappingStepComponent implements OnInit { this._cruvedStore.cruved.IMPORT.module_objects.MAPPING.cruved.U > 0; // const currentUser = this._authService.getCurrentUser(); - const intersectMappingOwnerUser = mappingValue['owners'].filter((x) => - x.identifiant == currentUser.user_login ? mappingValue['owners'] : false - ); if (this._fieldMappingService.mappingFormGroup.dirty && mappingValue && this.cruved.C) { + const intersectMappingOwnerUser = mappingValue['owners'].filter((x) => + x.identifiant == currentUser.user_login ? mappingValue['owners'] : false + ); if ( mappingValue.public && (hasAdminUpdateMappingRight || (hasOwnMappingUpdateRight && intersectMappingOwnerUser)) diff --git a/frontend/src/app/modules/imports/services/mappings/field-mapping.service.ts b/frontend/src/app/modules/imports/services/mappings/field-mapping.service.ts index 0d14afddcb..42db9c2aae 100644 --- a/frontend/src/app/modules/imports/services/mappings/field-mapping.service.ts +++ b/frontend/src/app/modules/imports/services/mappings/field-mapping.service.ts @@ -299,11 +299,7 @@ export class FieldMappingService { ); this.currentFieldMappingSubscription = this.currentFieldMapping.subscribe((fieldMapping) => { - this.fieldMappingStatus = { - mapped: new Set(), - unmapped: new Set(this.sourceFields), - autogenerated: new Set(), - }; + this.fieldMappingStatus.unmapped = new Set(this.sourceFields); if (fieldMapping === null) { this.mappingFormGroup.reset(); @@ -347,7 +343,7 @@ export class FieldMappingService { } else { if ( !this.sourceFields.includes(source) && - !(target in this.fieldMappingStatus.autogenerated) + !this.fieldMappingStatus.autogenerated.has(target) ) { return; } From e9bcc2af7b7dc31eac26fe8a20652f179ccec5aa Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Tue, 7 Jan 2025 11:44:50 +0100 Subject: [PATCH 10/25] fix(doc): fix some rendering issues in the documentation --- docs/admin-manual.rst | 176 +++++++++++++++---------------- docs/development.rst | 96 ++++++++--------- docs/https.rst | 10 +- docs/import-level-2.rst | 26 ++--- docs/installation-standalone.rst | 30 +++--- docs/tests_backend.rst | 40 +++---- docs/tests_frontend.rst | 16 +-- 7 files changed, 200 insertions(+), 194 deletions(-) diff --git a/docs/admin-manual.rst b/docs/admin-manual.rst index 93b3e10092..075e2b7f85 100644 --- a/docs/admin-manual.rst +++ b/docs/admin-manual.rst @@ -63,7 +63,7 @@ Celui-ci fonctionne grâce à des fichiers de migration qui sont appliqués de m Les fichiers de migrations de GeoNature se trouve dans le dossier ``backend/geonature/migrations/versions/``. Il est possible pour n’importe quelle dépendance ou module GeoNature de fournir également des fichiers de migrations. Pour que ceux-ci soient détectés par Alembic, il suffira de définir un point d’entrée dans le ``setup.py`` de la dépendance ou du module concerné : -.. code-block:: +.. code:: python setuptools.setup( …, @@ -77,7 +77,7 @@ Il est possible pour n’importe quelle dépendance ou module GeoNature de fourn Il est également possible de spécifier l’emplacement de révisions Alembic manuellement dans la configuration de GeoNature. Cela est nécessaire entre autre pour UsersHub afin de pouvoir manipuler son schéma alors que UsersHub n’est usuellement pas installé dans le venv de GeoNature (seul UsersHub-authentification-module l’est) : -.. code-block:: +.. code:: toml [ALEMBIC] VERSION_LOCATIONS = '/path/to/usershub/app/migrations/versions' @@ -91,9 +91,9 @@ Chaque fichier de migration est caractérisé par : Les commandes Alembic sont disponibles grâce à la sous-commande ``db`` de la commande ``geonature`` : -.. code-block:: +.. code:: shell - $ geonature db --help + geonature db --help Les deux sous-commandes ``status`` et ``autoupgrade`` sont spécifiques à GeoNature afin d’aider à l’utilisation d’Alembic. @@ -101,7 +101,7 @@ La commande ``status`` permet de visualiser les branches et l’ensemble de leur Pour chaque révision est indiqué si celle-ci est appliquée à la base de données. Si une branche a au moins sa première révision d’appliquée, alors un petit symbole indique si cette branche est à jour, c’est-à-dire si toutes les révisions de la branche ont été appliquées (``✓``) ou si la branche est en retard, c’est-à-dire que celle-ci contient des révisions qui ne sont pas encore appliquées à la base de données (``×``). -.. code-block:: +.. code:: shell [geonature ✓] [x] ┰ f06cc80cc8ba geonature schemas 2.7.5 @@ -214,9 +214,9 @@ Elle accepte également les paramètres ``-x`` qui sont alors fournis à la comm La commande ``heads`` permet de lister l’ensemble des branches disponibles, ainsi que la dernière révision disponible pour chaque branche : -.. code-block:: +.. code:: shell - $ geonature db heads + geonature db heads e0ac4c9f5c0a (ref_geo) (effective head) 7077aa76da3d (geonature) (head) 586613e2faeb (ref_geo_inpn_grids_1) (head) @@ -245,9 +245,9 @@ La commande ``heads`` permet de lister l’ensemble des branches disponibles, ai La commande ``history`` permet de lister l’ensemble de fichier de révisions. Il est également possible de lister les révisions devant être appliquées pour passer d’un état à un autre. Par exemple, voici la liste des révisions à appliquer pour passer d’une base de données vierge (``base``) à une base avec la branche ``nomenclatures_inpn_data`` à jour (``head``) : -.. code-block:: +.. code:: shell - $ geonature db history -r base:nomenclatures_inpn_data@head + geonature db history -r base:nomenclatures_inpn_data@head (6015397d686a) -> 96a713739fdd (nomenclatures_inpn_data) (effective head), insert inpn data in ref_nomenclatures (fa35dfe5ff27, 3842a6d800a0) -> 6015397d686a (nomenclatures) (effective head), create ref_nomenclature schema 1.3.9 -> 3842a6d800a0 (sql_utils) (effective head), Add public shared functions @@ -255,18 +255,18 @@ La commande ``history`` permet de lister l’ensemble de fichier de révisions. Si vous avez déjà une base de données existante correspondant à une installation de GeoNature en version 2.7.5 et que vous passez à Alembic, vous pouvez l’indiquer grâce à la commande suivante : -.. code-block:: +.. code:: shell - $ geonature db stamp f06cc80cc8ba + geonature db stamp f06cc80cc8ba Il est possible que votre base de données contienne quelques données supplémentaires (référentiel géographique des communes, …), qu’il faut donc indiquer à Alembic aussi. Reportez-vous aux notes de versions de la release 2.8.0 de GeoNature afin de consulter la liste des révisions à éventuellement « `stamper` ». Vous pouvez demander à Alembic dans quel état se trouve votre base de données avec la commande ``current`` : -.. code-block:: +.. code:: shell - $ geonature db current + geonature db current 62e63cd6135d (effective head) f06cc80cc8ba 3842a6d800a0 (effective head) @@ -286,9 +286,9 @@ Notons toutefois que Alembic ne stocke pas l’ensemble de cette liste dans la t Il est possible de n’afficher que les informations liées à une révision avec la commande ``show`` : -.. code-block:: +.. code:: shell - $ geonature db show f06cc80cc8ba + geonature db show f06cc80cc8ba Rev: f06cc80cc8ba Parent: Also depends on: 72f227e37bdf, a763fb554ff2, 46e91e738845, 6afe74833ed0 @@ -303,15 +303,15 @@ Il est possible de n’afficher que les informations liées à une révision ave L’absence de l’indication ``(head)`` à côté du numéro de révision indique qu’il ne s’agit pas de la dernière révision disponible pour la branche ``geonature``. Vous pouvez alors mettre à jour cette branche avec la commande ``upgrade`` : -.. code-block:: +.. code:: shell - $ geonature db upgrade geonature@head + geonature db upgrade geonature@head Il est possible de monter des branches optionnelles pour, par exemple, bénéficier des mailles 10×10 dans son référentiel géographique : -.. code-block:: +.. code:: shell - $ geonature db upgrade ref_geo_inpn_grids_10@head -x data-directory=./tmp_geo + geonature db upgrade ref_geo_inpn_grids_10@head -x data-directory=./tmp_geo L’ensemble des branches disponibles est décrit dans la sous-section ci-après. @@ -319,9 +319,9 @@ L’argument ``-x`` permet de fournir des variables à usage des fichiers de mig Pour supprimer les mailles 10×10 de son référentiel géographique, on utilisera : -.. code-block:: +.. code:: shell - $ geonature db downgrade ref_geo_inpn_grids_10@base + geonature db downgrade ref_geo_inpn_grids_10@base Dans le cas d’une branche contenant plusieurs migrations, on pourra appliquer ou désappliquer chaque migration individuellement avec ``upgrade branch@+1`` ou ``downgrade branch@-1``. Il est également possible de référencer directement un numéro de migration. @@ -329,10 +329,10 @@ Si l’on souhaite appliquer une migration manuellement, ou si l’on souhaite l Pour créer un nouveau fichier de migration afin d’y placer ses évolutions de la base de données, on utilisera la commande suivante : -.. code-block:: +.. code:: shell - $ geonature db revision -m "add table gn_commons.t_foo" --head geonature@head - Generating […]/backend/geonature/migrations/versions/31250092bce3_add_table_gn_commons_t_foo.py ... done + geonature db revision -m "add table gn_commons.t_foo" --head geonature@head + Generating […]/backend/geonature/migrations/versions/31250092bce3_add_table_gn_commons_t_foo.py ... done La `documentation d’Alembic `_ liste les opérations prises en charge. Certaines opérations complexes telles que la création de trigger ne sont pas prévues, mais il reste toujours possible d’exécuter du SQL directement avec l’opérateur ``op.execute``. @@ -374,9 +374,9 @@ Les branches ci-après sont totalement optionnelles : Note : pour plusieurs fichiers de révision, notamment liés au référentiel géographique ou nécessitant des données INPN, il est nécessaire de télécharger des ressources externes. Il est possible d’enregistrer les données téléchargées (et ne pas les re-télécharger si elles sont déjà présentes) avec ``-x data-directory=…`` : -.. code-block:: +.. code:: shell - $ geonature db upgrade …@head -x data-directory=./data/ + geonature db upgrade …@head -x data-directory=./data/ Gestion des droits @@ -575,7 +575,7 @@ A terme, d'autres variables pourront compléter ces profils : habitats (habref) Il est possible de désactiver l'ensemble des fonctionnalités liées aux profils dans l'interface, en utilisant le paramètre suivant dans le fichier ``geonature/config/geonature_config.toml`` -:: +.. code:: toml [FRONTEND] ENABLE_PROFILES = true/false @@ -1051,26 +1051,26 @@ Paramètres Gunicorn Voici les paramètres de Gunicorn par défaut : - * ``GUNICORN_PROC_NAME=geonature`` - * ``GUNICORN_NUM_WORKERS=4`` - * ``GUNICORN_HOST=127.0.0.1`` - * ``GUNICORN_PORT=8000`` - * ``GUNICORN_TIMEOUT=30`` +* ``GUNICORN_PROC_NAME=geonature`` +* ``GUNICORN_NUM_WORKERS=4`` +* ``GUNICORN_HOST=127.0.0.1`` +* ``GUNICORN_PORT=8000`` +* ``GUNICORN_TIMEOUT=30`` Pour modifier une de ces variables, créer un fichier ``environ`` à la racine de votre dossier GeoNature, et indiquer la variable d’environnement avec sa valeur modifiée. Si vous souhaitez modifier de manière plus avancée la ligne de commande ``gunicorn``, surcouchez le service systemd : - * Lancez ``sudo systemctl edit geonature`` ce qui va créer le fichier ``/etc/systemd/system/geonature.service.d/override.conf`` et ouvrir un éditeur pour vous permettre de le modifier - * Indiquez : - - .. code:: +* Lancez ``sudo systemctl edit geonature`` ce qui va créer le fichier ``/etc/systemd/system/geonature.service.d/override.conf`` et ouvrir un éditeur pour vous permettre de le modifier +* Indiquez : + + .. code:: conf - [Service] - ExecStart= - ExecStart=/path/to/venv/bin/unicorn geonature:create_app() … + [Service] + ExecStart= + ExecStart=/path/to/venv/bin/unicorn geonature:create_app() … - Note : le premier ``ExecStart`` permet de réinitialiser la commande de lancement de gunicorn. + Note : le premier ``ExecStart`` permet de réinitialiser la commande de lancement de gunicorn. Sauvegarde et restauration @@ -1083,18 +1083,18 @@ Sauvegarde Les sauvegardes de la BDD sont à faire avec l'utilisateur ``postgres``. Commencer par créer un répertoire et lui donner des droits sur le répertoire où seront faites les sauvegardes. -.. code-block:: console +.. code-block:: shell - $ # Créer le répertoire pour stocker les sauvegardes - $ mkdir /home/`whoami`/backup - $ # Ajouter l'utilisateur postgres au groupe de l'utilisateur linux courant pour qu'il ait les droits d'écrire dans les mêmes répertoires - $ sudo adduser postgres `whoami` - $ # ajout de droit aux groupes de l'utilisateur courant sur le répertoire `backup` - $ chmod g+rwx /home/`whoami`/backup + # Créer le répertoire pour stocker les sauvegardes + mkdir /home/`whoami`/backup + # Ajouter l'utilisateur postgres au groupe de l'utilisateur linux courant pour qu'il ait les droits d'écrire dans les mêmes répertoires + sudo adduser postgres `whoami` + # ajout de droit aux groupes de l'utilisateur courant sur le répertoire `backup` + chmod g+rwx /home/`whoami`/backup Connectez-vous avec l'utilisateur linux ``postgres`` pour lancer une sauvegarde de la BDD : -.. code-block:: console +.. code-block:: shell sudo su postgres pg_dump -Fc geonature2db > /home/`whoami`/backup/`date +%Y-%m-%d-%H:%M`-geonaturedb.backup @@ -1106,7 +1106,7 @@ Opération à faire régulièrement grâce à une tâche cron. * Sauvegarde des fichiers de configuration : - .. code-block:: console + .. code-block:: shell cd /home/`whoami`/geonature/config tar -zcvf /home/`whoami`/backup/`date +%Y%m%d%H%M`-geonature_config.tar.gz ./ @@ -1115,7 +1115,7 @@ Opération à faire à chaque modification d'un paramètre de configuration. * Sauvegarde des fichiers de customisation : - .. code-block:: console + .. code-block:: shell cd /home/`whoami`/geonature/custom tar -zcvf /home/`whoami`/`date +%Y%m%d%H%M`-geonature_custom.tar.gz ./ @@ -1124,7 +1124,7 @@ Opération à faire à chaque modification de la customisation de l'application. * Sauvegarde des modules externes : - .. code-block:: console + .. code-block:: shell cd /home/`whoami`/geonature/external_modules tar -zcvf /home/`whoami`/backup/`date +%Y%m%d%H%M`-external_modules.tar.gz ./ @@ -1136,7 +1136,7 @@ Restauration - Créer une base de données vierge (on part du principe que la base de données ``geonature2db`` n'existe pas ou plus). Sinon adaptez le nom de la BDD et également la configuration de connexion de l'application à la BDD dans ``/config/geonature_config.toml`` - .. code-block:: console + .. code-block:: shell sudo -n -u postgres -s createdb -O geonature2db sudo -n -u postgres -s psql -d geonature2db -c 'CREATE EXTENSION IF NOT EXISTS "postgis";' @@ -1149,7 +1149,7 @@ Restauration - Restaurer la BDD à partir du backup - .. code-block:: console + .. code-block:: shell sudo su postgres pg_restore -d geonature2db /201803150917-geonaturedb.backup @@ -1158,7 +1158,7 @@ Restauration - Décompresser les fichiers précédemment sauvegardés pour les remettre au bon emplacement : - .. code-block:: console + .. code-block:: shell sudo rm /config/* cd /config @@ -1318,6 +1318,7 @@ GeoNature est fourni avec des données géographiques de base sur la métropole * Videz le contenu des tables ``ref_geo.dem`` et éventuellement ``ref_geo.dem_vector`` * Uploadez le(s) fichier(s) du MNT sur le serveur * Suivez la procédure de chargement du MNT en l'adaptant : + * https://github.com/PnX-SI/GeoNature/blob/master/backend/geonature/migrations/versions/1715cf31a75d_insert_ign_250m_bd_alti_in_dem.py * https://github.com/PnX-SI/GeoNature/blob/master/backend/geonature/migrations/versions/87651375c2e8_vectorize_ign_bd_alti.py @@ -1376,7 +1377,7 @@ Affichage des référentiels géographiques dans GeoNature Il est possible de choisir les éléments des référentiels géographiques pouvant s'afficher sur les cartes. Par exemple si on souhaite modifier l'affichage des communes : -:: +.. code:: toml # Configuration par défaut : [[MAPCONFIG.REF_LAYERS]] @@ -1387,7 +1388,7 @@ Il est possible de choisir les éléments des référentiels géographiques pouv style = { color = "grey", fill = false, fillOpacity = "0.0", weight = 2 } params = {limit = 2000} # nombre d'éléments maximum pouvant être affichés -:: +.. code:: toml # Configuration modifiée [[MAPCONFIG.REF_LAYERS]] @@ -1444,7 +1445,7 @@ Depuis la version 2.1.0, UsersHub propose une API de création de compte utilisa Pour des raisons de sécurité, l'API de création de compte est réservée aux utilisateurs "admin" grâce à un token secret. GeoNature a donc besoin de se connecter en tant qu'administrateur à UsersHub pour éxecuter les requêtes d'administration de compte. Renseigner les paramètres suivants dans le fichier de configuration (``geonature_config.toml``). L'utilisateur doit avoir des droits 6 dans UsersHub -:: +.. code:: toml [USERSHUB] URL_USERSHUB = 'http://mon_adresse_usershub.fr' # sans slash final @@ -1454,7 +1455,7 @@ Renseigner les paramètres suivants dans le fichier de configuration (``geonatur Les fonctionnalités de création de compte nécessitent l'envoi d'emails pour vérifier l'identité des demandeurs de compte. Il est donc nécessaire d'avoir un serveur SMTP capable d'envoyer des emails. Renseigner la rubrique ``MAIL_CONFIG`` de la configuration. La description détaillées des paramètres de configuration d'envoie des emails est disponible dans `la documentation de Flask-Mail `_. Exemple : -:: +.. code:: toml [MAIL_CONFIG] MAIL_SERVER = 'mail.espaces-naturels.fr' @@ -1470,14 +1471,14 @@ Pour activer cette fonctionnalité (qui est par défaut désactivée), modifier NB : tous les paramètres décrits ci-dessous doivent être dans la rubrique ``[ACCOUNT_MANAGEMENT]`` -:: +.. code:: toml [ACCOUNT_MANAGEMENT] ENABLE_SIGN_UP = true Deux modes sont alors disponibles. Soit l'utilisateur est automatiquement accepté et un compte lui est créé après une confirmation de son email, soit un mail est envoyé à un administrateur pour confirmer la demande. Le compte ne sera crée qu'après validation par l'administrateur. Le paramètre ``AUTO_ACCOUNT_CREATION`` contrôle ce comportement (par défaut le compte créé sans validation par un administrateur: true). Dans le mode "création de compte validé par administrateur", il est indispensable de renseigner un email où seront envoyés les emails de validation (paramètre ``VALIDATOR_EMAIL``) -:: +.. code:: toml # automatique [ACCOUNT_MANAGEMENT] @@ -1496,7 +1497,7 @@ Dans le mode "création de compte validé par administrateur", lorsque l'inscrip Il est possible de personnaliser le texte de la partie finale de cet email située juste avant la signature à l'aide du paramètre ``ADDON_USER_EMAIL`` (toujours à ajouter à la rubrique ``[ACCOUNT_MANAGEMENT]``). Vous pouvez utiliser des balises HTML compatibles avec les emails pour ce texte. -:: +.. code:: toml [ACCOUNT_MANAGEMENT] ADDON_USER_EMAIL = """

@@ -1506,7 +1507,7 @@ Vous pouvez utiliser des balises HTML compatibles avec les emails pour ce texte. Il est également possible de créer automatiquement un jeu de données et un cadre d'acquisition "personnel" à l'utilisateur afin qu'il puisse saisir des données dès sa création de compte via le paramètre ``AUTO_DATASET_CREATION``. Par la suite l'administrateur pourra rattacher l'utilisateur à des JDD et CA via son organisme. -:: +.. code:: toml [ACCOUNT_MANAGEMENT] AUTO_ACCOUNT_CREATION = true @@ -1525,7 +1526,7 @@ Il est possible d'ajouter des champs au formulaire grâce à un générateur con L'exemple ci-dessous permet de créer un champs de type "checkbox" obligatoire, avec un lien vers un document (une charte par exemple) et un champ de type "select", non obligatoire. (voir le fichier ``config/geonature_config.toml.example`` pour un exemple plus exhaustif). -:: +.. code:: toml [ACCOUNT_MANAGEMENT] [[ACCOUNT_MANAGEMENT.ACCOUNT_FORM]] @@ -1553,7 +1554,7 @@ Un espace "utilisateur" est accessible lorsque l'on est connecté, permettant de Cet espace est activable grâce au paramètre ``ENABLE_USER_MANAGEMENT``. Par défaut, il est désactivé. -:: +.. code:: toml [ACCOUNT_MANAGEMENT] AUTO_ACCOUNT_CREATION = true @@ -1649,7 +1650,7 @@ Pour plus de souplesse et afin de répondre aux besoins de chacun, l'ensemble de En modifiant les variables des champs ci-dessous, vous pouvez donc personnaliser le formulaire : -:: +.. code:: toml [form_fields] date_min = true @@ -1771,8 +1772,7 @@ La liste des champs affichés par défaut dans le tableau peut être modifiée a Par défaut : -:: - +.. code:: toml default_maplist_columns = [ { prop = "taxons", name = "Taxon" }, @@ -1886,7 +1886,7 @@ Dans l'exemple ci-dessous, remplacez ```` par le contenu de la colo Bien que le module soit une copie d'Occtax, il est tout de même nécessaire de définir les permissions disponibles pour ce module (ce sont les mêmes qu'Occtax). Jouez le scrit SQL suivant en remplacant :MODULE_CODE par le code du module que vous venez de créer. -:: +.. code:: sql INSERT INTO gn_permissions.t_permissions_available ( @@ -1929,7 +1929,7 @@ Ajouter le nouveau module dans la liste des modules implémentés Dans le fichier de configuration de GeoNature (geonature_config.toml) ajoutez une section `ADDITIONAL_FIELDS` qui contient tableau `IMPLEMENTED_MODULES` listant les modules qui implémentent les champs additionnels (Occtax doit y figurer en plus du nouveau module) -:: +.. code::toml [ADDITIONAL_FIELDS] IMPLEMENTED_MODULES = ["OCCTAX", "FLORE_STATION"] @@ -1981,9 +1981,9 @@ Exemples : - Un champs de type "datalist". Ce champs permet de générer une liste de valeurs à partir d'une API (non porté sur Occtax-mobile). Dans le champ "attributs additionnels", renseignez les éléments suivants : -:: +.. code:: json - ``{"api": "url_vers_la_ressource", "keyValue": "champ à stocker en base", "keyLabel": "champ à afficher en interface"} + {"api": "url_vers_la_ressource", "keyValue": "champ à stocker en base", "keyLabel": "champ à afficher en interface"} Configuration avancée des champs ```````````````````````````````` @@ -2010,7 +2010,7 @@ Le module OCCHAB fait partie du coeur de GeoNature. Son installation est au choi Pour l'installer, lancer les commandes suivantes : -.. code-block:: console +.. code-block:: shell cd backend source venv/bin/activate @@ -2046,7 +2046,7 @@ Formulaire - L'ensemble des champs du formulaire son masquables. Pour en masquer certains, passer à ``false`` les variables suivantes : -:: +.. code:: toml [formConfig] date_min = true @@ -2085,7 +2085,7 @@ L'ensemble des paramètres de configuration du module se trouve dans le fichier Editer la variable ``AREA_FILTERS`` en y ajoutant le label et le code du type d'entité géographique que vous souhaitez rajouter. Voir table ``ref_geo.bib_areas_types``. Dans l'exemple on ajoute le type ZNIEFF1 (``code_type = "ZNIEFF1"``). Attention, dans ce cas les entités géographiques correspondantes au type `ZNIEFF1`, doivent également être présentes dans la table ``ref_geo.l_areas``. Attention : Si des données sont déjà présentes dans la synthèse et que l'on ajoute de nouvelles entités géographiques à ``ref_geo.l_areas``, il faut également recalculer les valeurs de la table ``gn_synthese.cor_area_synthese`` qui assure la correspondance entre les données de la synthèse et les entités géographiques. -:: +.. code:: toml [SYNTHESE] # Liste des entités géographiques sur lesquels les filtres @@ -2109,7 +2109,7 @@ Il est possible de ne pas intégrer certains champs présents dans cette vue d'e Enlevez la ligne de la colonne que vous souhaitez désactiver. Les noms de colonne de plus de 10 caractères seront tronqués dans l'export au format shapefile. -:: +.. code::toml [SYNTHESE] EXPORT_COLUMNS = [ @@ -2190,13 +2190,13 @@ Enlevez la ligne de la colonne que vous souhaitez désactiver. Les noms de colon "date_modification" ] -:Note: +.. note:: L'entête ``[SYNTHESE]`` au dessus ``EXPORT_COLUMNS`` indique simplement que cette variable appartient au bloc de configuration de la synthese. Ne pas rajouter l'entête à chaque paramètre de la synthese mais une seule fois au dessus de toutes les variables de configuration du module. Il est également possible de personnaliser ses exports en créant vos propres vues personnalisées et en remplissant le paramètre suivant avec une ou plusieurs vues d'export spécifiques : -:: +.. code:: toml [SYNTHESE] ... @@ -2233,7 +2233,7 @@ Ces seuils sont modifiables respectivement par les variables ``NB_MAX_OBS_MAP`` Le mode cluster activé par défaut peut être désactivé via le paramètre ``ENABLE_LEAFLET_CLUSTER``. Dans ce cas, il est conseillé de repasser le paramètre `NB_MAX_OBS_MAP` à 10000. -:: +.. code:: toml [SYNTHESE] # Nombre d'observation maximum à afficher sur la carte après une recherche @@ -2247,7 +2247,7 @@ L'interface de recherche de la synthèse permet de filtrer sur l'ensemble des no Modifiez la variable ``EXCLUDED_COLUMNS`` -:: +.. code:: toml [SYNTHESE] EXCLUDED_COLUMNS = ['non_digital_proof'] # pour enlever le filtre 'preuve non numérique' @@ -2265,7 +2265,7 @@ Ces paramètres se présentent sous la forme d'une liste de dictionnaires. Il es Voici un exemple : -:: +.. code:: toml [SYNTHESE] RED_LISTS_FILTERS = [ @@ -2293,7 +2293,7 @@ Pour cela, il suffit de mettre une valeur ``false`` dans le champ ``enable`` de Exemple de requête de mise à jour de la table ``taxonomie.bdc_statut_text`` pour désactiver les textes des DOM-TOM : : -:: +.. code:: sql UPDATE taxonomie.bdc_statut_text SET enable = false WHERE cd_sig IN ('TER971', 'TER972', 'TER973', 'TER971', 'TER974' ) @@ -2301,7 +2301,7 @@ Exemple de requête de mise à jour de la table ``taxonomie.bdc_statut_text`` po Une commande dans TaxHub permet de désactiver automatiquement les textes en dehors d'une liste de départements (en passant leur ``area_code``) : -:: +.. code:: bash source ~/geonature/backend/venv/bin/activate geonature taxref enable-bdc-statut-text -d -d --clean @@ -2315,7 +2315,7 @@ Il faut fournir le code des nomenclature par défaut (liste de chaîne de caract Exemple de filtres par défaut : -:: +.. code::toml [SYNTHESE] ... @@ -2357,7 +2357,7 @@ Liste des champs visibles Gestion de l'affichage des colonnes de la liste via le paramètre ``COLUMN_LIST`` : -:: +.. code:: toml [[COLUMN_LIST]] column_label = "nomenclature_life_stage.label_default" # Champs de la synthèse, éventuellement en suivant des relationships @@ -2392,7 +2392,7 @@ Activation L'activation de la validation automatique s'effectue en ajoutant la ligne suivante dans le fichier de configuration du module de validation ``config/validation_config.toml`` : -:: +.. code:: toml AUTO_VALIDATION_ENABLED = true @@ -2401,8 +2401,8 @@ Conditions de validation automatique Une observation sera validée automatiquement si elle rencontre les conditions suivantes : - * Son statut de validation est ``En attente de validation`` - * Si le score calculé à partir du profil de taxons est de 3. Se référer à la section `Profils de taxons`_ pour plus d'informations. +* Son statut de validation est ``En attente de validation`` +* Si le score calculé à partir du profil de taxons est de 3. Se référer à la section `Profils de taxons`_ pour plus d'informations. Si ces conditions sont remplies, alors le statut de validation de l'observation est mis à ``Probable``. @@ -2414,7 +2414,7 @@ Modification de la périodicité de la validation automatique Le processus de validation automatique est exécuté à une fréquence définie, par défaut toutes les heures. Si toutefois, vous souhaitez diminuer ou augmenter la durée entre chaque validation automatique, définissez cette dernière dans le fichier de configuration (``config/validation_config.toml``) dans la variable ``AUTO_VALIDATION_CRONTAB``. -:: +.. code::toml AUTO_VALIDATION_CRONTAB ="*/1 * * * *" diff --git a/docs/development.rst b/docs/development.rst index 30ba724604..c6536d10e9 100644 --- a/docs/development.rst +++ b/docs/development.rst @@ -41,7 +41,7 @@ Vous pouvez obtenir la liste des routes de GeoNature avec la commande suivante : .. code-block:: bash - $ geonature routes + geonature routes Documentation des routes @@ -80,7 +80,7 @@ Backend - Utiliser *blake* comme formateur de texte et activer l'auto-formatage dans son éditeur de texte (Tuto pour VsCode : https://medium.com/@marcobelo/setting-up-python-black-on-visual-studio-code-5318eba4cd00) - La longueur maximale pour une ligne de code est 100 caractères. Pour VSCODE copier ces lignes le fichier ``settings.json`` : -:: +.. code:: python "python.formatting.blackArgs": [ "--line-length", @@ -138,7 +138,7 @@ HTML - Revenir à la ligne avant et après le contenue d'une balise. - Lorsqu'il y a plus d'un attribut sur une balise, revenir à la ligne, aligner les attributs et aller a la ligne pour fermer la balise : -:: +.. code:: html @@ -97,12 +97,12 @@ Lancement Pour lancer Cypress et executer les tests à la main il faut exécuter la commande (nécessite qu'une instance GeoNature fonctionne (backend+frontend)): -.. code-block:: bash +.. code:: bash - $ npm run cypress:open + npm run cypress:open Pour lancer les test en mode automatique, il faut exécuter la commande (utilisée dans l'intégration continue (GitHub Action)): -.. code-block:: bash +.. code:: bash - $ npm run e2e:ci && npm run e2e:coverage + npm run e2e:ci && npm run e2e:coverage From 2c3ff70dd9d7756ba0b87078bc87ddad6d96dcd0 Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Tue, 7 Jan 2025 13:47:35 +0100 Subject: [PATCH 11/25] feat(doc): add copy button on code block + minor changes on the doc --- docs/installation-all.rst | 40 ++++++++++++++++---------------- docs/installation-standalone.rst | 26 ++++++++++----------- docs/installation.rst | 16 ++++++------- docs/requirements.in | 3 ++- docs/requirements.txt | 3 +++ setup.py | 1 + 6 files changed, 47 insertions(+), 42 deletions(-) diff --git a/docs/installation-all.rst b/docs/installation-all.rst index acccff9f1b..ade7f723ee 100644 --- a/docs/installation-all.rst +++ b/docs/installation-all.rst @@ -40,11 +40,11 @@ Configuration * Renseignez à minima : - * ``my_url`` : l'URL (ou IP) de votre serveur (avec un ``/`` à la fin) - * ``user_pg`` : l'utilisateur PostgreSQL que vous souhaitez voir créé - * ``user_pg_pass`` : mot de passe de l'utilisateur PostgreSQL - - Le script se chargera d'installer PostgreSQL, de crééer la base de donnée et de créer l'utilisateur que vous avez renseigné. + * ``my_url`` : l'URL (ou IP) de votre serveur (avec un ``/`` à la fin) + * ``user_pg`` : l'utilisateur PostgreSQL que vous souhaitez voir créé + * ``user_pg_pass`` : mot de passe de l'utilisateur PostgreSQL + + Le script se chargera d'installer PostgreSQL, de crééer la base de donnée et de créer l'utilisateur que vous avez renseigné. * Variable ``mode`` @@ -57,17 +57,17 @@ Installation * Lancer l'installation : - .. code:: console + .. code:: shell - $ touch install_all.log - $ chmod +x install_all.sh - $ ./install_all.sh 2>&1 | tee install_all.log + touch install_all.log + chmod +x install_all.sh + ./install_all.sh 2>&1 | tee install_all.log Une fois l'installation terminée, lancez la commande suivante: - .. code:: console + .. code:: shell - $ exec bash + exec bash Les applications sont disponibles aux adresses suivantes : @@ -77,36 +77,36 @@ Les applications sont disponibles aux adresses suivantes : Vous pouvez vous connecter avec l'utilisateur intégré par défaut (admin/admin). -:Note: +.. note:: Pour en savoir plus TaxHub, sa configuration et son utilisation, reportez-vous à sa documentation : https://taxhub.readthedocs.io. Idem pour UsersHub et sa documentation : https://usershub.readthedocs.io -:Note: +.. note:: * GeoNature-atlas compatible avec GeoNature V2 est disponible sur https://github.com/PnX-SI/GeoNature-atlas * Vous pouvez utiliser le schéma ``ref_geo`` de GeoNature pour votre territoire, les communes et les mailles. Si vous rencontrez une erreur, se reporter aux fichiers de logs ``/home/`whoami`/install_all.log``. -:Note: +.. note:: Si vous souhaitez que GeoNature soit à la racine du serveur, ou à une autre adresse, editez le fichier de configuration Apache (``/etc/apache2/sites-available/geonature.conf``) en modifiant l'alias : - Pour ``/``: ``Alias / /home/test/geonature/frontend/dist`` - Pour ``/saisie`` : ``Alias /saisie /home/test/geonature/frontend/dist`` -:Note: +.. note:: Par défaut et par mesure de sécurité, la base de données est accessible uniquement localement par la machine où elle est installée. Pour accéder à la BDD depuis une autre machine (pour s'y connecter avec QGIS, pgAdmin ou autre), vous pouvez consulter cette documentation https://github.com/PnX-SI/Ressources-techniques/blob/master/PostgreSQL/acces-bdd.rst. Attention, exposer la base de données sur internet n'est pas recommandé. Il est préférable de se connecter via un tunnel SSH. QGIS et la plupart des outils d'administration de base de données permettent d'établir une connexion à la base de cette manière. Attention si vous redémarrez PostgreSQL (``sudo service postgresql restart``), il faut ensuite redémarrer les API de GeoNature et UsersHub : - .. code:: console + .. code:: shell - $ sudo systemctl restart geonature - $ sudo systemctl restart geonature-worker - $ sudo systemctl restart usershub + sudo systemctl restart geonature + sudo systemctl restart geonature-worker + sudo systemctl restart usershub -:Note: +.. note:: Il est aussi important de configurer l'accès au serveur en HTTPS plutôt qu'en HTTP pour chiffrer le contenu des échanges entre le navigateur et le serveur (https://docs.ovh.com/fr/hosting/les-certificats-ssl-sur-les-hebergements-web/). diff --git a/docs/installation-standalone.rst b/docs/installation-standalone.rst index e40676e78e..0654aa0b43 100644 --- a/docs/installation-standalone.rst +++ b/docs/installation-standalone.rst @@ -9,9 +9,9 @@ Installation des dépendances Installer les paquets suivants : -:: +.. code:: shell - $ sudo apt install unzip git postgresql-postgis postgis python3-pip python3-venv python3-dev libpq-dev libgdal-dev libffi-dev libpangocairo-1.0-0 apache2 redis + sudo apt install unzip git postgresql-postgis postgis python3-pip python3-venv python3-dev libpq-dev libgdal-dev libffi-dev libpangocairo-1.0-0 apache2 redis Récupération de l'application @@ -21,30 +21,30 @@ Récupération de l'application * Récupérer l'application (``X.Y.Z`` à remplacer par le numéro de la `dernière version stable de GeoNature `_). - :: + .. code:: shell - $ wget https://github.com/PnX-SI/GeoNature/archive/X.Y.Z.zip + wget https://github.com/PnX-SI/GeoNature/archive/X.Y.Z.zip * Dézipper l'archive de l'application - :: + .. code:: shell - $ unzip X.Y.Z.zip - $ rm X.Y.Z.zip + unzip X.Y.Z.zip + rm X.Y.Z.zip * Renommer le répertoire de l'application puis placez-vous dedans : - :: + .. code:: shell - $ mv GeoNature-X.Y.Z /home/`whoami`/geonature/ - $ cd geonature + mv GeoNature-X.Y.Z /home/`whoami`/geonature/ + cd geonature * Copier puis mettre à jour le fichier de configuration (``config/settings.ini``) comportant les informations relatives à votre environnement serveur : - :: + .. code:: shell - $ cp config/settings.ini.sample config/settings.ini - $ nano config/settings.ini + cp config/settings.ini.sample config/settings.ini + nano config/settings.ini Installation de l'application diff --git a/docs/installation.rst b/docs/installation.rst index 2424058582..996191ac3b 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -95,27 +95,27 @@ Commencer la procédure en se connectant au serveur en SSH avec l'utilisateur li * Lui donner ensuite les droits administrateur en l’ajoutant au groupe ``sudo`` : - .. code:: console + .. code:: shell - # adduser geonatureadmin sudo + adduser geonatureadmin sudo .. note:: Vérifier les droits du répertoire HOME de l'utilisateur - Il doit être en ``7XX`` soit ``drwxr-xr-x``. Si ce n'est pas le cas, exécuter la commande suivante : - - .. code:: console + Il doit être en ``7XX`` soit ``drwxr-xr-x``. Si ce n'est pas le cas, exécuter la commande suivante : - # chmod 755 /home/geonatureadmin + .. code:: console + + # chmod 755 /home/geonatureadmin * Pour la suite du processus d’installation, on utilisera l'utilisateur non privilégié nouvellement créé. Si besoin d'éxecuter des commandes avec les droits d'administrateur, on les précèdera de ``sudo``. Il est d'ailleurs possible renforcer la sécurité du serveur en bloquant la connexion SSH au serveur avec ``root``. Voir https://docs.ovh.com/fr/vps/conseils-securisation-vps/ pour plus d'informations sur le sécurisation du serveur. Pour passer de l’utilisateur ``root`` à ``geonatureadmin``, vous pouvez aussi utiliser la commande : - .. code:: console + .. code:: shell - # su - geonatureadmin + su - geonatureadmin .. _installation-all: diff --git a/docs/requirements.in b/docs/requirements.in index ba2fc4bfca..f5da392f20 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -1,4 +1,5 @@ sphinx sphinx-book-theme myst-parser -sphinx-autoapi \ No newline at end of file +sphinx-autoapi +sphinx-copybutton \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt index 566459a632..b6348ffcde 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -74,10 +74,13 @@ sphinx==7.4.7 # pydata-sphinx-theme # sphinx-autoapi # sphinx-book-theme + # sphinx-copybutton sphinx-autoapi==3.3.3 # via -r requirements.in sphinx-book-theme==1.1.3 # via -r requirements.in +sphinx-copybutton==0.5.2 + # via -r requirements.in sphinxcontrib-applehelp==2.0.0 # via sphinx sphinxcontrib-devhelp==2.0.0 diff --git a/setup.py b/setup.py index 40bde971db..b57572fdd0 100644 --- a/setup.py +++ b/setup.py @@ -45,6 +45,7 @@ "sphinx-book-theme", "myst-parser", "sphinx-autoapi", + "sphinx-copybutton", ], }, classifiers=[ From c0d3438b06ee072e8ebfbcc986336ceec18acc27 Mon Sep 17 00:00:00 2001 From: Camille Monchicourt Date: Tue, 7 Jan 2025 14:01:44 +0100 Subject: [PATCH 12/25] Delete docs/import-level-2.rst Moved to https://github.com/PnX-SI/Ressources-techniques/blob/master/GeoNature/V2/import-avance/readme.md --- docs/import-level-2.rst | 379 ---------------------------------------- 1 file changed, 379 deletions(-) delete mode 100644 docs/import-level-2.rst diff --git a/docs/import-level-2.rst b/docs/import-level-2.rst deleted file mode 100644 index 1649671c16..0000000000 --- a/docs/import-level-2.rst +++ /dev/null @@ -1,379 +0,0 @@ -IMPORT NIVEAU 2 -""""""""""""""" - -Description -``````````` - -L'exercice consiste à importer le fichier -https://github.com/PnX-SI/Ressources-techniques/blob/master/GeoNature/V2/import-avance/observations.csv dans GeoNature V2. - -1 - On charge le fichier CSV dans une table de la base de données. - -2 - On prépare la table importée (FK et typage des champs si besoin). - -3 - On créé les métadonnées pour que GeoNature sache identifier les nouvelles données. - -4 - On mappe les champs de la table d'import avec ceux de la synthèse. - - Pour cela on utilise une fonction dédiée qui nous prépare le travail. Il ne reste plus qu'à finaliser le mapping (la fonction ne peut pas tout deviner). - -5 - On crée la requête d'import. - - Pour cela on utilise une fonction dédiée qui nous prépare le travail. On adapte la requête produite par la fonction. - -6 - On importe les données en synthèse. - -7 - On gère les nouveaux taxons vis à vis la saisie. - -8 - On archive la table où on veut. - - -1 - Import du fichier CSV -````````````````````````` - -Cette action doit être faite par un superuser PostgreSQL. - -.. note:: - - * Le fichier CSV doit être présent localement sur le serveur hébergeant la base de données. - * Il fichier doit être encodé en UTF-8 et la première ligne doit comporter le nom des champs. - * Le séparateur de champs doit être le point-virgule. - * La fonction utilise la fonction ``COPY`` capable de lire le système de fichier du serveur. Pour des raisons de sécurité, cette fonction ``COPY`` n'est accessible qu'aux superutilisateurs. Vous devez donc disposer d'un accès superutilisateur PostgreSQL pour utiliser cette fonction d'import. Si l'utilisateur connecté à la base dans pgAdmin n'est pas superuser, on peut le faire dans psql. - -Dans un terminal - -.. code:: shell - - sudo su postgres - psql -d geonature2db - -Dans les 2 cas, copier-coller les 2 commandes ci-dessous en adaptant les chemins et l'utilisateur. - -.. code:: sql - - SELECT gn_imports.load_csv_file('/home/myuser/imports/observations.csv', 'gn_imports.testimport'); - ALTER TABLE gn_imports.testimport OWNER TO geonatuser; - -.. note:: - - * Attention : si la table existe, elle est supprimée et recréée à partir du CSV fourni. - * La fonction créé la table et sa structure dans le schéma et la table fournie en paramètre. - * Le contenu du fichier CSV est chargé dans la table (initialement toutes les colonnes sont de type ``text``). - * La function tente ensuite d'identifier et de modifier le type de chacune des colonnes à partir du contenu et seuls les types ``integer``, ``real``, et ``date`` sont actuellement reconnus. - * Si vous devez modifier manuellement le type d'une colonne, vous pouvez vous inspirer du code ci-dessous. - - -2 - Préparation de la nouvelle table contenant les données importées -```````````````````````````````````````````````````````````````````` - -**Ajouter une clé primaire sur la table importée** - -.. code:: sql - - ALTER TABLE gn_imports.testimport ADD PRIMARY KEY (id_data); - -Si la table ne comporte pas de champ permettant une identification unique des observations : - -.. code:: sql - - ALTER TABLE gn_imports.testimport - ADD COLUMN gid serial; - - ALTER TABLE gn_imports.testimport - ADD CONSTRAINT pk_testimport PRIMARY KEY(gid); - -**Si besoin de mettre à jour le type de certains champs de la table importée** - -.. code:: sql - - ALTER TABLE monschema.matable ALTER COLUMN macolonne TYPE montype USING macolonne::montype; - -En l'état vos données sont importées et stockées dans la base GeoNature. Cependant GeoNature ne connait pas ces données. Pour qu'elles soient utilisables, au moins en consultation, vous devez fournir à l'application GeoNature un certain nombre d'informations concernant ces données et à minima les importer dans la synthèse. Vous pouvez également les importer dans un autre module, comme "Occtax" (non abordé dans cet exemple). - - -3 - Création des métadonnées -```````````````````````````` - -Il est nécessaire de rattacher les données importées à un jeu de données qui doit appartenir à un cadre d'acquisition. Si ceux-ci n'ont pas encore été créés dans la base, vous devez le faire dans ``gn_meta.t_acquisition_frameworks`` pour le cadre d'acquisition et dans ``gn_meta.t_datasets`` pour le jeu de données. Vous pouvez pour cela utiliser les formulaires disponibles dans l'interface d'aministration de GeoNature : http://myurl/geonature/#/admin - -Le jeu de données doit être rattaché à un protocole décrivant la manière dont les données ont été collectées. - -.. note:: - - Noter les ID retournés lors des insertions. - -.. code:: sql - - INSERT INTO gn_meta.sinp_datatype_protocols ( protocol_name, protocol_desc, id_nomenclature_protocol_type, protocol_url) - VALUES ('ATBI', 'Inventaire ATBI Dans la réserve de Lauvitel - Date_debut : 2013-01-01 - Date_fin : 3000-01-01', 395, NULL) returning id_protocol; - -.. code:: sql - - INSERT INTO gn_meta.t_datasets(id_acquisition_framework, dataset_name, dataset_shortname, dataset_desc, id_nomenclature_data_type, keywords, marine_domain, terrestrial_domain, active) - VALUES (1, 'Observations Flavia 2017', 'Observations Flavia 2017', 'Données ATBI Flavia pour l''année 2017', 326, 'Invertébrés, PNE, ATBI', FALSE, TRUE, TRUE) returning id_dataset; - -Il est également nécessaire, pour la synthese, de lui indiquer où sont stockées les données qu'elle contient et comment y accèder. Vous devez pour cela disposer d'une source de données dans ``gn_synthese.t_sources`` correspondant aux données à importer. Pour l'exemple nous allons créer une source de données avec la commande SQL suivante : - -.. code:: sql - - INSERT INTO gn_synthese.t_sources(name_source, desc_source) - VALUES('ATBI', 'Données d''inventaire ATBI') returning id_source; - -.. note:: - - * D'autres valeurs sont attendues mais pour l'exercice, le fichier source utilise des valeurs insérée à titre d'exemple lors de la création de la base GeoNature. - * ``id_role`` 3 et 4 dans ``utilisateurs.t_roles`` - * ``id_organisme`` 1 dans ``utilisateurs.bib_organismes`` - -.. note:: - - Il est possible d'utiliser ce mécanisme générique pour insérer des données de n'importe quelle table vers n'importe quelle autre, à partir du moment où il est possible d'établir un mapping cohérent entre les champs et notamment que les types puissent correspondre ou soient "transtypables". - - -4 - Création du mapping (source --> cible) -`````````````````````````````````````````` - -Le schéma gn_imports comporte trois tables permettant de préparer le mapping des champs entre la table importée (source) et une table de destination (target). - -* ``gn_imports.matching_tables`` permet de déclarer la table source et la table de destination. Noter le ``id_matching_table`` généré par la séquence lors de l'insertion d'un nouveau "matching" dans cette table. -* ``gn_imports.matching_fields`` permet de faire le matching entre les champs de la table source et de la table de destination. Vous devez indiquer le type de chacun des champs de la table de destination ainsi que le ``id_matching_table``. -* ``gn_imports.matching_geoms`` permet de préparer la création du geom dans la table de destination à partir du ou des champs constituant le geom fourni dans la table source : champs contenant les x et y pour un format ``xy`` ou le champ comportant le wkt pour le format ``wkt``. - -En attendant la création d'une interface permettant de faciliter l'import, vous devez remplir ces tables manuellement. Cependant, la fonction ``gn_imports.fct_generate_mapping('table_source', 'table_cible', forcedelete)`` permet de pré-générer un mapping. - -Si le mapping source/cible existe, la fonction ne fait rien et un message d'erreur est levé. Si le mapping n'existe pas ou si le paramètre ``forcedelete (boolean default = false)`` est à ``true``, la fonction crée le mapping en remplissant la table ``gn_imports.matching_tables`` et la table``gn_imports.matching_fields`` avec une ligne par champ de la table cible. Il ne vous reste plus qu'à manuellement supprimer ou remplacer les valeurs 'replace me' dans le champs source_field ou les valeurs par défaut proposées par la fonction. - -**Pré-générer les champs à mapper** - -.. code:: sql - - SELECT gn_imports.fct_generate_matching('gn_imports.testimport', 'gn_synthese.synthese'); - SELECT gn_imports.fct_generate_matching('gn_imports.testimport', 'gn_synthese.cor_observer_synthese'); - -OU si besoin d'écraser un mapping des champs existants - -.. code:: sql - - SELECT gn_imports.fct_generate_matching('gn_imports.testimport', 'gn_synthese.synthese', true); - SELECT gn_imports.fct_generate_matching('gn_imports.testimport', 'gn_synthese.cor_observer_synthese',true); - -IL FAUT ICI METTRE A JOUR LA TABLE ``gn_imports_matching_fields`` pour établir manuellement la correspondance des champs entre la table source et la table cible (voir le mapping final pour le fichier CSV fourni en exemple à la fin de cette page). - -.. note:: - - * Au moins un des 2 champs ``source_field`` ou ``source_default_value`` doit être renseigné. - * Si le champ ``source_field`` est renseigné, le champ ``source_default_value`` est ignoré. - -Une fois que le mapping est renseigné, vous pouvez passer à l'étape suivante. - - -5 - Construire la requête d'import -`````````````````````````````````` - -Attention, pgAdmin va tronquer le résultat. Pour obtenir l'ensemble de la requête utiliser le bouton d'export du résultat dans un fichier ou executé la requête avec psql. - -**Génération de la requête d'import dans les tables de destination** - -.. code:: sql - - SELECT gn_imports.fct_generate_import_query('gn_imports.testimport', 'gn_synthese.synthese'); - SELECT gn_imports.fct_generate_import_query('gn_imports.testimport', 'gn_synthese.cor_observer_synthese'); - -.. note:: - - Utiliser le bouton d'export du resultat de la requete de pgadmin ou utiliser psql. - Il est necessaire d'adapter la requête si besoin de faire des jointures pour récupérer des valeurs dans d'autres tables - - -6 - Chargement des données dans la table de destination (synthese ici) -`````````````````````````````````````````````````````````````````````` - -Voir la requête d'import en synthèse à la fin de cette page. - - -7 - Déplacement de la table importée (facultatif) -````````````````````````````````````````````````` - -On peut si on le souhaite déplacer la table vers une destination d'archivage - -.. code:: sql - - ALTER TABLE gn_imports.testimport SET SCHEMA schema_destination; - -On peut la mettre dans le schéma gn_exports pour l'exercice afin de tester mais ce n'est pas sa vocation. - -Résultat Final -`````````````` - -.. code:: sql - - --DELETE FROM gn_imports.matching_fields WHERE id_matching_table IN (1,2); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (207, NULL, 'uuid_generate_v4()', 'unique_id_sinp', 'uuid', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (208, NULL, 'uuid_generate_v4()', 'unique_id_sinp_grp', 'uuid', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (219, NULL, 'gn_synthese.get_default_nomenclature_value(''PREUVE_EXIST''::character varying)', 'id_nomenclature_exist_proof', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (210, 'id_data', NULL, 'entity_source_pk_value', 'character varying', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (211, 'id_lot', NULL, 'id_dataset', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (209, 'id_source', NULL, 'id_source', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (213, NULL, 'gn_synthese.get_default_nomenclature_value(''TYP_GRP''::character varying)', 'id_nomenclature_grp_typ', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (212, NULL, 'gn_synthese.get_default_nomenclature_value(''NAT_OBJ_GEO''::character varying)', 'id_nomenclature_geo_object_nature', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (214, NULL, 'gn_synthese.get_default_nomenclature_value(''METH_OBS''::character varying)', 'id_nomenclature_obs_meth', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (215, NULL, 'gn_synthese.get_default_nomenclature_value(''TECHNIQUE_OBS''::character varying)', 'id_nomenclature_obs_technique', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (217, NULL, 'gn_synthese.get_default_nomenclature_value(''ETA_BIO''::character varying)', 'id_nomenclature_bio_condition', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (216, NULL, 'gn_synthese.get_default_nomenclature_value(''STATUT_BIO''::character varying)', 'id_nomenclature_bio_status', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (218, NULL, 'gn_synthese.get_default_nomenclature_value(''NATURALITE''::character varying)', 'id_nomenclature_naturalness', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (220, NULL, 'gn_synthese.get_default_nomenclature_value(''STATUT_VALID''::character varying)', 'id_nomenclature_valid_status', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (221, NULL, 'gn_synthese.get_default_nomenclature_value(''NIV_PRECIS''::character varying)', 'id_nomenclature_diffusion_level', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (223, NULL, 'gn_synthese.get_default_nomenclature_value(''SEXE''::character varying)', 'id_nomenclature_sex', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (222, NULL, 'gn_synthese.get_default_nomenclature_value(''STADE_VIE''::character varying)', 'id_nomenclature_life_stage', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (224, NULL, 'gn_synthese.get_default_nomenclature_value(''OBJ_DENBR''::character varying)', 'id_nomenclature_obj_count', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (226, NULL, 'gn_synthese.get_default_nomenclature_value(''SENSIBILITE''::character varying)', 'id_nomenclature_sensitivity', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (225, NULL, 'gn_synthese.get_default_nomenclature_value(''TYP_DENBR''::character varying)', 'id_nomenclature_type_count', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (227, NULL, 'gn_synthese.get_default_nomenclature_value(''STATUT_OBS''::character varying)', 'id_nomenclature_observation_status', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (228, NULL, 'gn_synthese.get_default_nomenclature_value(''DEE_FLOU''::character varying)', 'id_nomenclature_blurring', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (230, NULL, 'gn_synthese.get_default_nomenclature_value(''TYP_INF_GEO''::character varying)', 'id_nomenclature_info_geo_type', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (229, NULL, 'gn_synthese.get_default_nomenclature_value(''STATUT_SOURCE''::character varying)', 'id_nomenclature_source_status', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (233, 'cd_nom', NULL, 'cd_nom', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (237, NULL, 'NULL', 'digital_proof', 'text', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (238, NULL, 'NULL', 'non_digital_proof', 'text', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (239, 'altitude_retenue', NULL, 'altitude_min', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (240, 'altitude_retenue', NULL, 'altitude_max', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (244, 'dateobs', NULL, 'date_min', 'timestamp without time zone', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (245, 'dateobs', NULL, 'date_max', 'timestamp without time zone', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (246, NULL, 'NULL', 'validator', 'character varying', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (248, NULL, 'NULL', 'observers', 'character varying', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (247, NULL, 'NULL', 'validation_comment', 'text', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (250, NULL, 'gn_synthese.get_default_nomenclature_value(''METH_DETERMIN''::character varying)', 'id_nomenclature_determination_method', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (252, NULL, 'now()', 'meta_validation_date', 'timestamp without time zone', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (253, NULL, 'now()', 'meta_create_date', 'timestamp without time zone', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (254, NULL, 'now()', 'meta_update_date', 'timestamp without time zone', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (255, NULL, '''c''', 'last_action', 'character', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (235, NULL, 'gn_commons.get_default_parameter(''taxref_version'',NULL)::character varying', 'meta_v_taxref', 'character varying', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (251, 'remarques', NULL, 'comments', 'text', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (231, 'effectif_total', NULL, 'count_min', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (232, 'effectif_total', NULL, 'count_max', 'integer', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (258, 'taxon_saisi', NULL, 'nom_cite', 'character varying', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (249, NULL, 'u.nom_role || '' '' || u.prenom_role', 'determiner', 'character varying', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (234, 'taxon_saisi', NULL, 'nom_cite', 'character varying', NULL, 1); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (256, 'id_data', NULL, 'entity_source_pk_value', 'integer', NULL, 2); - INSERT INTO gn_imports.matching_fields (id_matching_field, source_field, source_default_value, target_field, target_field_type, field_comments, id_matching_table) VALUES (257, 'observateurs', NULL, 'id_role', 'integer', NULL, 2); - INSERT INTO gn_imports.matching_geoms (id_matching_geom, source_x_field, source_y_field, source_geom_field, source_geom_format, source_srid, target_geom_field, target_geom_srid, geom_comments, id_matching_table) VALUES (1, 'x', 'y', NULL, 'xy', 2154, 'the_geom_local', 2154, NULL, 1); - INSERT INTO gn_imports.matching_geoms (id_matching_geom, source_x_field, source_y_field, source_geom_field, source_geom_format, source_srid, target_geom_field, target_geom_srid, geom_comments, id_matching_table) VALUES (2, NULL, NULL, 'POINT(6.064544 44.28787)', 'wkt', 4326, 'the_geom_4326', 4326, NULL, 1); - INSERT INTO gn_imports.matching_geoms (id_matching_geom, source_x_field, source_y_field, source_geom_field, source_geom_format, source_srid, target_geom_field, target_geom_srid, geom_comments, id_matching_table) VALUES (1, 'x', 'y', NULL, 'xy', 4326, 'the_geom_point', 4326, NULL, 1); - - SELECT pg_catalog.setval('gn_imports.matching_fields_id_matching_field_seq', 258, true); - SELECT pg_catalog.setval('gn_imports.matching_geoms_id_matching_geom_seq', 3, true); - SELECT pg_catalog.setval('gn_imports.matching_tables_id_matching_table_seq', 2, true); - - --------------- - --IMPORT DATA-- - --------------- - --autogenerated query by - --SELECT gn_imports.fct_generate_import_query('gn_imports.testimport', 'gn_synthese.cor_observer_synthese'); - INSERT INTO gn_synthese.synthese( - unique_id_sinp - ,unique_id_sinp_grp - ,id_nomenclature_exist_proof - ,entity_source_pk_value - ,id_dataset - ,id_source - ,id_nomenclature_grp_typ - ,id_nomenclature_geo_object_nature - ,id_nomenclature_obs_meth - ,id_nomenclature_obs_technique - ,id_nomenclature_bio_condition - ,id_nomenclature_bio_status - ,id_nomenclature_naturalness - ,id_nomenclature_valid_status - ,id_nomenclature_diffusion_level - ,id_nomenclature_sex - ,id_nomenclature_life_stage - ,id_nomenclature_obj_count - ,id_nomenclature_sensitivity - ,id_nomenclature_type_count - ,id_nomenclature_observation_status - ,id_nomenclature_blurring - ,id_nomenclature_info_geo_type - ,id_nomenclature_source_status - ,cd_nom - ,digital_proof - ,non_digital_proof - ,altitude_min - ,altitude_max - ,date_min - ,date_max - ,validator - ,observers - ,validation_comment - ,id_nomenclature_determination_method - ,meta_validation_date - ,meta_create_date - ,meta_update_date - ,last_action - ,meta_v_taxref - ,comments - ,count_min - ,count_max - ,nom_cite - ) - SELECT - uuid_generate_v4()::uuid AS unique_id_sinp - ,uuid_generate_v4()::uuid AS unique_id_sinp_grp - ,gn_synthese.get_default_nomenclature_value('PREUVE_EXIST'::character varying)::integer AS id_nomenclature_exist_proof - ,a.id_data::character varying AS entity_source_pk_value - ,a.id_lot::integer AS id_dataset - ,a.id_source::integer AS id_source - ,gn_synthese.get_default_nomenclature_value('TYP_GRP'::character varying)::integer AS id_nomenclature_grp_typ - ,gn_synthese.get_default_nomenclature_value('NAT_OBJ_GEO'::character varying)::integer AS id_nomenclature_geo_object_nature - ,gn_synthese.get_default_nomenclature_value('METH_OBS'::character varying)::integer AS id_nomenclature_obs_meth - ,gn_synthese.get_default_nomenclature_value('TECHNIQUE_OBS'::character varying)::integer AS id_nomenclature_obs_technique - ,gn_synthese.get_default_nomenclature_value('ETA_BIO'::character varying)::integer AS id_nomenclature_bio_condition - ,gn_synthese.get_default_nomenclature_value('STATUT_BIO'::character varying)::integer AS id_nomenclature_bio_status - ,gn_synthese.get_default_nomenclature_value('NATURALITE'::character varying)::integer AS id_nomenclature_naturalness - ,gn_synthese.get_default_nomenclature_value('STATUT_VALID'::character varying)::integer AS id_nomenclature_valid_status - ,gn_synthese.get_default_nomenclature_value('NIV_PRECIS'::character varying)::integer AS id_nomenclature_diffusion_level - ,gn_synthese.get_default_nomenclature_value('SEXE'::character varying)::integer AS id_nomenclature_sex - ,gn_synthese.get_default_nomenclature_value('STADE_VIE'::character varying)::integer AS id_nomenclature_life_stage - ,gn_synthese.get_default_nomenclature_value('OBJ_DENBR'::character varying)::integer AS id_nomenclature_obj_count - ,gn_synthese.get_default_nomenclature_value('SENSIBILITE'::character varying)::integer AS id_nomenclature_sensitivity - ,gn_synthese.get_default_nomenclature_value('TYP_DENBR'::character varying)::integer AS id_nomenclature_type_count - ,gn_synthese.get_default_nomenclature_value('STATUT_OBS'::character varying)::integer AS id_nomenclature_observation_status - ,gn_synthese.get_default_nomenclature_value('DEE_FLOU'::character varying)::integer AS id_nomenclature_blurring - ,gn_synthese.get_default_nomenclature_value('TYP_INF_GEO'::character varying)::integer AS id_nomenclature_info_geo_type - ,gn_synthese.get_default_nomenclature_value('STATUT_SOURCE'::character varying)::integer AS id_nomenclature_source_status - ,a.cd_nom::integer AS cd_nom - ,NULL::text AS digital_proof - ,NULL::text AS non_digital_proof - ,a.altitude_retenue::integer AS altitude_min - ,a.altitude_retenue::integer AS altitude_max - ,a.dateobs::timestamp without time zone AS date_min - ,a.dateobs::timestamp without time zone AS date_max - ,NULL::character varying AS validator - ,NULL::character varying AS observers - ,NULL::text AS validation_comment - ,gn_synthese.get_default_nomenclature_value('METH_DETERMIN'::character varying)::integer AS id_nomenclature_determination_method - ,now()::timestamp without time zone AS meta_validation_date - ,now()::timestamp without time zone AS meta_create_date - ,now()::timestamp without time zone AS meta_update_date - ,'c'::character AS last_action - ,gn_commons.get_default_parameter('taxref_version',NULL)::character varying::character varying AS meta_v_taxref - ,a.remarques::text AS comments - ,a.effectif_total::integer AS count_min - ,a.effectif_total::integer AS count_max - ,taxon_saisi - FROM gn_imports.testimport a - ; - - --autogenerated query by - --SELECT gn_imports.fct_generate_import_query('gn_imports.testimport', 'gn_synthese.cor_observer_synthese'); - INSERT INTO gn_synthese.cor_observer_synthese( - id_role - ,id_synthese - ) - SELECT - a.observateurs::integer AS id_role - ,s.id_synthese::integer AS id_synthese - FROM gn_imports.testimport a - --self addition - JOIN gn_synthese.synthese s ON s.entity_source_pk_value::integer = a.id_data - WHERE s.id_source = 4; - ; From d338f533847d0e6b045672cc8cee8618ff3be41c Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Tue, 7 Jan 2025 15:35:55 +0100 Subject: [PATCH 13/25] change theme to furo --- docs/conf.py | 6 +++--- docs/requirements.in | 2 +- docs/requirements.txt | 28 ++++++++++------------------ setup.py | 2 +- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 2c16584f8b..045ff8e079 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -73,9 +73,9 @@ # built documents. # # The short X.Y version. -version = "2.0" +version = "2.15.0" # The full version, including alpha/beta/rc tags. -release = "2.0" +release = "2.15.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -101,7 +101,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = "sphinx_book_theme" +html_theme = "furo" html_logo = "./images/LogoGeonature.jpg" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/docs/requirements.in b/docs/requirements.in index f5da392f20..5c09bf5705 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -1,5 +1,5 @@ sphinx -sphinx-book-theme +furo myst-parser sphinx-autoapi sphinx-copybutton \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt index b6348ffcde..fcec0ad78e 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,18 +4,14 @@ # # pip-compile requirements.in # -accessible-pygments==0.0.5 - # via pydata-sphinx-theme alabaster==0.7.16 # via sphinx astroid==3.3.5 # via sphinx-autoapi babel==2.16.0 - # via - # pydata-sphinx-theme - # sphinx + # via sphinx beautifulsoup4==4.12.3 - # via pydata-sphinx-theme + # via furo certifi==2024.8.30 # via requests charset-normalizer==3.4.0 @@ -23,8 +19,9 @@ charset-normalizer==3.4.0 docutils==0.21.2 # via # myst-parser - # pydata-sphinx-theme # sphinx +furo==2024.8.6 + # via -r requirements.in idna==3.10 # via requests imagesize==1.4.1 @@ -50,12 +47,9 @@ myst-parser==3.0.1 # via -r requirements.in packaging==24.1 # via sphinx -pydata-sphinx-theme==0.16.0 - # via sphinx-book-theme pygments==2.18.0 # via - # accessible-pygments - # pydata-sphinx-theme + # furo # sphinx pyyaml==6.0.2 # via @@ -70,15 +64,15 @@ soupsieve==2.6 sphinx==7.4.7 # via # -r requirements.in + # furo # myst-parser - # pydata-sphinx-theme # sphinx-autoapi - # sphinx-book-theme + # sphinx-basic-ng # sphinx-copybutton sphinx-autoapi==3.3.3 # via -r requirements.in -sphinx-book-theme==1.1.3 - # via -r requirements.in +sphinx-basic-ng==1.0.0b2 + # via furo sphinx-copybutton==0.5.2 # via -r requirements.in sphinxcontrib-applehelp==2.0.0 @@ -98,9 +92,7 @@ stdlib-list==0.11.0 tomli==2.0.2 # via sphinx typing-extensions==4.12.2 - # via - # astroid - # pydata-sphinx-theme + # via astroid urllib3==2.2.3 # via requests zipp==3.20.2 diff --git a/setup.py b/setup.py index b57572fdd0..ede27b522a 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ ], "doc": [ "sphinx", - "sphinx-book-theme", + "furo", "myst-parser", "sphinx-autoapi", "sphinx-copybutton", From 925ed863b8a6ce9a1292975247c362a390a5a9e1 Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Tue, 7 Jan 2025 15:48:37 +0100 Subject: [PATCH 14/25] feat(doc): limit depth of right section --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 045ff8e079..ecbe59f0c9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -108,7 +108,7 @@ # documentation. # html_theme_options = { - "navigation_depth": 4, + "navigation_depth": 2, "use_source_button": True, "repository_provider": "github", "repository_url": "https://github.com/PnX-SI/GeoNature", From c0900d1a5bb9598420d7d05d6fca7683da04fe6d Mon Sep 17 00:00:00 2001 From: Camille Monchicourt Date: Tue, 7 Jan 2025 16:08:30 +0100 Subject: [PATCH 15/25] Delete docs/import-level-1.rst Moved to https://github.com/PnX-SI/Ressources-techniques/blob/master/GeoNature/V2/import-basique/readme.md --- docs/import-level-1.rst | 168 ---------------------------------------- 1 file changed, 168 deletions(-) delete mode 100644 docs/import-level-1.rst diff --git a/docs/import-level-1.rst b/docs/import-level-1.rst deleted file mode 100644 index 5c71f2a645..0000000000 --- a/docs/import-level-1.rst +++ /dev/null @@ -1,168 +0,0 @@ -IMPORT NIVEAU 1 -""""""""""""""" - -Dans cet exemple, nous allons importer un fichier CSV (ou SHP) d'observations dans la base de données de GeoNature, -pour ensuite intégrer ces données dans la synthèse de GeoNature. - -On utilisera le fichier d'exemple -https://github.com/PnX-SI/Ressources-techniques/blob/master/GeoNature/V2/import-basique/01-observations-faune-2008-2010.csv. - -Importer la donnée source dans la BDD avec QGIS -``````````````````````````````````````````````` - -PS : Si vous utilisez un CSV, vous pouvez aussi utiliser la fonction ``gn_imports.load_csv_file``. - -**1.** Connecter la BDD dans QGIS : - -* QGIS -* PostGIS / Clic droit / New connection -* Nom / Hôte (IP) / Base de données (geonaturedb) / Authentification de base (utilisateur / mot de passe) -* Parcourir les tables géométriques - -Si vous devez ouvrir les connexions externes à votre BDD, -voir la documentation https://github.com/PnEcrins/GeoNature-atlas/blob/master/docs/installation.rst#acc%C3%A9der-%C3%A0-votre-bdd - -**2.** Importer le fichier dans la BDD : - -* Ouvrir SHP ou CSV dans QGIS -* Bases de données / Gestionnaire de base de données -* Sélectionner la BDD et son schéma -* Importer une couche/un fichier -* Choisir la couche à importer et définir le nom de table de destination - -Créer les métadonnées -````````````````````` - -**1.** Ajouter une source (si elle n'existe pas déjà) - -En l'ajoutant manuellement dans la table ``gn_synthese.t_sources`` ou en SQL : - -.. code:: sql - - INSERT INTO gn_synthese.t_sources(name_source, desc_source) - VALUES - ('Historique', 'Données historiques intégrées manuellement dans la BDD') - -**2.** Ajouter un jeu de données (si il n'existe pas déja) - -Avec l'admin de GeoNature, dans la BDD avec pgAdmin ou en SQL. Et avant ça un CA si il n'en existe pas déjà un auquel associer le JDD. - -.. code:: sql - - INSERT INTO gn_meta.t_datasets(id_acquisition_framework, dataset_name, dataset_shortname, dataset_desc, id_nomenclature_data_type, keywords, marine_domain, terrestrial_domain, active) - VALUES - (1, 'Données Faune 2008-2010', 'Faune 2008-2010', 'Données faune du PNE entre 2008 et 2010', 326, 'Faune, PNE', FALSE, TRUE, TRUE) - -Pour retrouver les valeurs d'un type de nomenclature, vous pouvez utiliser les vues qui les rendent plus lisibles. -Par exemple ici ``ref_nomenclatures.v_data_typ``. -Ou bien l'Admin des nomenclatures disponible dans GeoNature. - -Il est aussi possible d'utiliser les codes des nomenclatures pour retrouver leurs id (ceci étant variables d'une instance à l'autre), -en utilisant la fonction ``ref_nomenclatures.get_id_nomenclature``. - -Insertion des données dans la Synthèse -`````````````````````````````````````` - -.. code:: sql - - INSERT INTO gn_synthese.synthese( - unique_id_sinp, - id_source, - id_dataset, - id_nomenclature_obs_technique, - count_min, - count_max, - cd_nom, - nom_cite, - altitude_min, - altitude_max, - the_geom_4326, - the_geom_point, - the_geom_local, - date_min, - date_max, - observers, - comments, - last_action - ) - SELECT - uuid_generate_v4(), -- Attention, ne générez un UUID_SINP pour chaque obs que si vous êtes surs qu'elles n'en ont pas déjà un - 2 AS id_source, - 3 AS id_dataset, - CASE - WHEN critere = 'Vu' THEN (select ref_nomenclatures.get_id_nomenclature('METH_OBS','0')) - WHEN critere = 'Entendu' THEN (select ref_nomenclatures.get_id_nomenclature('METH_OBS','1')) - ELSE (gn_synthese.get_default_nomenclature_value('METH_OBS')) - END AS id_nomenclature_obs_meth, - effectif::integer, - effectif::integer, - cd_nom::integer, - taxon_latin, - altitude::integer, -- On pourrait calculer les valeurs manquantes avec la fonction ref_geo.fct_get_altitude_intersection - altitude::integer, - ST_SetSRID(ST_MakePoint("x_WGS84"::numeric, "y_WGS84"::numeric),4326) AS the_geom_4326, - ST_Centroid(ST_SetSRID(ST_MakePoint("x_WGS84"::numeric, "y_WGS84"::numeric),4326)) AS the_geom_point, - ST_Transform(ST_SetSRID(ST_MakePoint("x_WGS84"::numeric, "y_WGS84"::numeric),4326),2154) AS the_geom_local, - dateobs::date, - dateobs::date, - observateurs, - remarques, - 'I' AS last_action -- code de la dernière action effectuée: Valeurs possibiles 'I': insert, 'U': update - FROM gn_imports.obs_faune_2008_2010 - ORDER BY dateobs - ; - -A creuser pour calculer les altitudes non renseignées : - -.. code:: sql - - SELECT id_synthese, - (ref_geo.fct_get_altitude_intersection(the_geom_local)).altitude_min - (ref_geo.fct_get_altitude_intersection(the_geom_local)).altitude_max - FROM gn_synthese.synthese - LIMIT 1000; - -Gil propose de rajouter une PK et de faire un lien entre les données de la table importée et celles dans la synthèse avec ``entity_source_pk_value`` : - -.. code:: sql - - -- Clé primaire - ALTER TABLE gn_imports.obs_faune_2008_2010 - ADD COLUMN gid serial; - - ALTER TABLE gn_imports.obs_faune_2008_2010 - ADD CONSTRAINT pk_obs_faune_2008_2010 PRIMARY KEY(gid); - -Ajouter le champ ``entity_source_pk_value`` dans ton INSERT et ``gid`` dans le SELECT. - -On pourrait aussi remplir ``cor_observers_synthese`` si on le veut et si on a les observateurs présents dans les données, -en les faisant correspondre avec leurs ``id_role``. - -L'installation de GeoNature intègre les communes de toute la France métropolitaine. Pour alléger la table ``ref_geo.l_areas``, il peut être pertinent de supprimer les communes en dehors du territoire de travail. Par exemple, supprimer toutes les communes en dehors du département. - -Pour retrouver le détail de toutes les communes du département Bouches-du-Rhône : - -.. code:: sql - - SELECT * FROM ref_geo.l_areas la - JOIN ref_geo.bib_areas_types ba ON ba.id_type = la.id_type - JOIN ref_geo.li_municipalities lm ON lm.id_area = la.id_area - WHERE ba.type_code = 'COM' AND lm.insee_dep = '13' - -A utiliser dans une requête de suppression, en gérant les cascades entre les tables. - -Insertion depuis un shapefile -````````````````````````````` - -L'exercice est similaire si on part depuis un fichier Shape -(https://github.com/PnX-SI/Ressources-techniques/blob/master/GeoNature/V2/import-basique/01-observations-faune-2008-2010-SHP.zip) - -La seule différence est que la géométrie est calculée lors de l'import de QGIS vers PostGIS. - -Ainsi la partie Géométrie de la requête d'insertion dans la Synthèse serait : - -.. code:: sql - - ST_Transform(ST_SetSRID(geom,2154),4326 AS the_geom_4326, - ST_Centroid(ST_SetSRID(geom,2154) AS the_geom_point, - geom AS the_geom_local, From f90a32344969bd7d5cc190378a669223e3bb448e Mon Sep 17 00:00:00 2001 From: Camille Monchicourt Date: Tue, 7 Jan 2025 16:15:41 +0100 Subject: [PATCH 16/25] Doc admin - Move manual import into https://github.com/PnX-SI/Ressources-techniques/tree/master/GeoNature/V2 --- docs/admin-manual.rst | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/docs/admin-manual.rst b/docs/admin-manual.rst index 075e2b7f85..ae34b688f0 100644 --- a/docs/admin-manual.rst +++ b/docs/admin-manual.rst @@ -1407,19 +1407,10 @@ Il peut s'agir de données partenaires, de données historiques ou de données s 2 possibilités s'offrent à vous : -* Créer un schéma dédié aux données pour les intégrer de manière complète et en extraire les DEE dans la Synthèse -* N'intégrer que les DEE dans la Synthèse +* Utiliser le module Import intégré à GeoNature +* Importer les données manuellement directement dans la BDD, dans la Synthèse ou dans les tables d'un module de saisie -Nous présenterons ici la première solution qui est privilégiée pour disposer des données brutes mais aussi les avoir dans la Synthèse. - -* Créer un JDD dédié (``gn_meta.t_datasets``) ou utilisez-en un existant. Eventuellement un CA si elles ne s'intègrent pas dans un CA déjà existant. -* Ajouter une Source de données dans ``gn_synthese.t_sources`` ou utilisez en une existante. -* Créer le schéma dédié à accueillir les données brutes. -* Créer les tables nécessaires à accueillir les données brutes. -* Intégrer les données dans ces tables (avec les fonctions de ``gn_imports``, avec QGIS ou pgAdmin). -* Pour alimenter la Synthèse à partir des tables sources, vous pouvez mettre en place des triggers (en s'inspirant de ceux de OccTax) ou bien faire une requête spécifique si les données sources ne sont plus amenées à évoluer. - -Pour des exemples plus précis, illustrées et commentées, vous pouvez consulter les 2 exemples d'import dans cette documentation (Import niveau et Import niveau 2). +Pour des exemples d'imports manuels précis, illustrés et commentés, vous pouvez consulter ceux partagés dans l'espace de ressources techniques : https://github.com/PnX-SI/Ressources-techniques/tree/master/GeoNature/V2. Vous pouvez aussi vous inspirer des exemples avancés de migration des données de GeoNature V1 vers GeoNature V2 : https://github.com/PnX-SI/GeoNature/tree/master/data/migrations/v1tov2 @@ -1428,12 +1419,6 @@ Vous pouvez aussi vous inspirer des exemples avancés de migration des données * Import continu : https://github.com/PnX-SI/Ressources-techniques/tree/master/GeoNature/migration/generic * Import d'un CSV historique (Flavia) : https://github.com/PnX-SI/Ressources-techniques/blob/master/GeoNature/V2/2018-12-csv-vers-synthese-FLAVIA.sql - -.. include:: import-level-1.rst - -.. include:: import-level-2.rst - - Authentification -------------------- From 51dbf2a17f6bd0ee174840520061cf1ae938730f Mon Sep 17 00:00:00 2001 From: Camille Monchicourt Date: Wed, 8 Jan 2025 14:05:25 +0100 Subject: [PATCH 17/25] Complement CHANGELOG 2.15.1 --- docs/CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index b2f62b6da3..0f6785e27a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,11 +6,22 @@ - Amélioration de la recherche libre des métadonnées en cherchant chaque mot indépendamment (#3295, par @jbrieuclp) - Amélioration de l'affichage de la photo du taxon sur les fiches taxon (#3287, par @edelclaux) +- Conversion du changelog en format markdown (#3297, par @jacquesfize) +- Ajout d'un fichier `Makefile` pour faciliter l'usage des commandes de développement (#3300, par @jacquesfize & @edelclaux) +- Complément et mise en forme de la documentation et publication sur Readthedocs (#3306, par @jacquesfize) +- Ajout des nouvelles mailles INPN lors de l'installation de GeoNature (#3293, par @jacquesfize) **🐛 Corrections** - Correction de la pagination quand on filtre les discussions de la page d'accueil sur "Mes discussions" (#3288, par @edelclaux) - Correction du nombre de taxons sur les fiches des cadres d'acquisition (#3228, par @jacquesfize) +- Correction de la redirection de l'authentification (#3305, par @jacquesfize) +- Correction des performances de la requête de récupération des discussions (#3307, par @jacquesfize) +- [Import] Correction de l'export des rapports d'import Occhab (#3293, par @jacquesfize) +- [Import] Correction de la selection automatique du JDD lors de l'import depuis la fiche d'un JDD (#3293, par @jacquesfize) +- [Import] Correction de la mise à jour des mappings publics (#3293, par @jacquesfize) +- [Import] Correction de la sauvegarde des checkbox dans le mapping des champs (#3293, par @Pierre-Narcisi) +- [Import] Correction de la sélection des champs `auto_generate` (#3293, par @Pierre-Narcisi) ## 2.15.0 - Pavo cristatus 🦚 (2025-12-11) From 4f0444cfbf407da092cb63d1e54ab4b207410128 Mon Sep 17 00:00:00 2001 From: jacquesfize Date: Wed, 8 Jan 2025 14:17:23 +0100 Subject: [PATCH 18/25] feat(gitignore): add geonature.local.env in the gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 87ea72f8f0..e03de8810e 100755 --- a/.gitignore +++ b/.gitignore @@ -155,4 +155,5 @@ install_all/install_all.log /docs/CHANGELOG.html /contrib/*/frontend/node_modules -Makefile.local \ No newline at end of file +Makefile.local +geonature.local.env \ No newline at end of file From 03ad862950c4a9ead7f96894447aee1e691f8fae Mon Sep 17 00:00:00 2001 From: Pierre-Narcisi Date: Fri, 8 Nov 2024 15:53:33 +0100 Subject: [PATCH 19/25] fix(pdf_ca): make modifs for acquisition framework pdf export MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List of modifications: - Display label rather than ID for nomenclature_territorial_level associated to "Etendue territoriale" - Do not display "Cible taxonomique" section if `data['target_description']` is empty i.e. if there is no information to display - Change "Liste des jeux de données associés au cadre" to "Liste des jeux de données associés" - Add count of Synthese observations for each dataset listed, associated to "Nombre d'observations" // change `get_export_pdf_acquisition_frameworks` endpoint to add these counts - Use `data.datasets` rather than `data.t_datasets` --- backend/geonature/core/gn_meta/routes.py | 9 +++++++++ .../acquisition_framework_template_pdf.html | 17 ++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/backend/geonature/core/gn_meta/routes.py b/backend/geonature/core/gn_meta/routes.py index ec6052f509..6a13c9e60b 100644 --- a/backend/geonature/core/gn_meta/routes.py +++ b/backend/geonature/core/gn_meta/routes.py @@ -618,6 +618,15 @@ def get_export_pdf_acquisition_frameworks(id_acquisition_framework): dataset_ids = [d.id_dataset for d in af.datasets] nb_data = len(dataset_ids) + # Add count of Synthese observations for each dataset + for dataset in acquisition_framework["datasets"]: + dataset_count_query = ( + select(func.count(Synthese.id_synthese)) + .select_from(Synthese) + .where(Synthese.id_dataset == dataset["id_dataset"]) + ) + dataset["count_synthese_observations"] = DB.session.scalar(dataset_count_query) + query = ( select(func.count(Synthese.cd_nom)) .select_from(Synthese) diff --git a/backend/geonature/templates/acquisition_framework_template_pdf.html b/backend/geonature/templates/acquisition_framework_template_pdf.html index e716288462..adc4b9b17a 100644 --- a/backend/geonature/templates/acquisition_framework_template_pdf.html +++ b/backend/geonature/templates/acquisition_framework_template_pdf.html @@ -187,7 +187,7 @@

Territoires concernés

{% if data['id_nomenclature_territorial_level']: %} - Etendue territoriale : {{ data['id_nomenclature_territorial_level'] }} + Etendue territoriale : {{ data['nomenclature_territorial_level']['label_fr'] }} {% endif %}