From 4566804294b1c828c30c3289053abb0d25a9c083 Mon Sep 17 00:00:00 2001 From: Jean-Pascal MILCENT Date: Sun, 24 Apr 2022 17:16:09 +0200 Subject: [PATCH] Feat speciesSheet: custom attributes for infos bloc Close #412. --- atlas/atlasRoutes.py | 5 +- atlas/configuration/config.py.example | 11 +- atlas/configuration/config_schema.py | 13 +- atlas/configuration/settings.ini.sample | 13 +- .../repositories/vmCorTaxonAttribut.py | 32 ++--- atlas/templates/speciesSheet/blocInfos.html | 119 +++++++++--------- data/atlas/14.grant.sql | 2 +- data/atlas/9.atlas.vm_cor_taxon_attribut.sql | 8 -- data/atlas/9.atlas.vm_taxon_attribute.sql | 18 +++ .../atlas.refresh_materialized_view_data.sql | 2 +- data/gn2/atlas_ref_taxonomie.sql | 5 +- data/update/update_attribute.sql | 63 ++++++++++ docs/vues_materialisees_maj.rst | 4 +- install_db.sh | 6 +- 14 files changed, 181 insertions(+), 120 deletions(-) delete mode 100644 data/atlas/9.atlas.vm_cor_taxon_attribut.sql create mode 100644 data/atlas/9.atlas.vm_taxon_attribute.sql create mode 100644 data/update/update_attribute.sql diff --git a/atlas/atlasRoutes.py b/atlas/atlasRoutes.py index 21b95163..5c225a5f 100644 --- a/atlas/atlasRoutes.py +++ b/atlas/atlasRoutes.py @@ -254,10 +254,7 @@ def ficheEspece(cd_nom): taxonDescription = vmCorTaxonAttribut.getAttributesTaxon( connection, cd_ref, - current_app.config["ATTR_DESC"], - current_app.config["ATTR_COMMENTAIRE"], - current_app.config["ATTR_MILIEU"], - current_app.config["ATTR_CHOROLOGIE"], + current_app.config["DISPLAYED_ATTR"], ) observers = vmObservationsRepository.getObservers(connection, cd_ref) diff --git a/atlas/configuration/config.py.example b/atlas/configuration/config.py.example index 88c2e0c2..a7568112 100644 --- a/atlas/configuration/config.py.example +++ b/atlas/configuration/config.py.example @@ -207,11 +207,12 @@ REDIMENSIONNEMENT_IMAGE = False # si REDIMENSIONNEMENT_IMAGE = True, indiquer l'URL de TaxHub TAXHUB_URL = "http://mondomaine.fr/taxhub" -#### ID DES ATTRIBUTS DESCRIPTIFS DES TAXONS DE LA TABLE vm_cor_taxon_attribut -ATTR_DESC = 100 -ATTR_COMMENTAIRE = 101 -ATTR_MILIEU = 102 -ATTR_CHOROLOGIE = 103 +#### LISTE DES CODES DES ATTRIBUTS DESCRIPTIFS DES TAXONS DE LA TABLE vm_taxon_attribute +# Un onglet sera affiché dans le bloc "Informations espèces" de la fiche espèce +# pour chaque code d'attribut indiqué dans la liste ci-dessous. +# L'onglet n'est affiché que s'il possède du contenu. +# L'ordre des onglets correspond à l'ordre des codes dans la liste. +DISPLAYED_ATTR=["atlas_description", "atlas_commentaire", "atlas_milieu", "atlas_chorologie"] #### ID DES TYPES DE MEDIAS DE LA TABLE vm_medias ATTR_MAIN_PHOTO = 1 diff --git a/atlas/configuration/config_schema.py b/atlas/configuration/config_schema.py index 068944a7..e756bc1c 100644 --- a/atlas/configuration/config_schema.py +++ b/atlas/configuration/config_schema.py @@ -154,10 +154,15 @@ class Meta: REMOTE_MEDIAS_PATH = fields.String(load_default="static/medias/") REDIMENSIONNEMENT_IMAGE = fields.Boolean(load_default=False) TAXHUB_URL = fields.String(required=False, load_default=None) - ATTR_DESC = fields.Integer(load_default=100) - ATTR_COMMENTAIRE = fields.Integer(load_default=101) - ATTR_MILIEU = fields.Integer(load_default=102) - ATTR_CHOROLOGIE = fields.Integer(load_default=103) + DISPLAYED_ATTR = fields.List( + fields.String(), + load_default=[ + "atlas_description", + "atlas_commentaire", + "atlas_milieu", + "atlas_chorologie", + ], + ) ATTR_MAIN_PHOTO = fields.Integer(load_default=1) ATTR_OTHER_PHOTO = fields.Integer(load_default=2) ATTR_LIEN = fields.Integer(load_default=3) diff --git a/atlas/configuration/settings.ini.sample b/atlas/configuration/settings.ini.sample index 712ebe21..6d6b905c 100644 --- a/atlas/configuration/settings.ini.sample +++ b/atlas/configuration/settings.ini.sample @@ -35,11 +35,11 @@ owner_atlas_pass=monpassachanger geonature_source=true # L'atlas est-il en lien avec le référentiel géographique de GeoNature (ref_geo) ? -# ATTENTION : Doit être égal à true si geonature_source=true, +# ATTENTION : Doit être égal à true si geonature_source=true, # ATTENTION : Doit être égal à false si geonature_source=false use_ref_geo_gn2=true -# Souhaitez-vous installer le schéma taxonomie de TaxHub dans la BDD de GeoNature-atlas ? +# Souhaitez-vous installer le schéma taxonomie de TaxHub dans la BDD de GeoNature-atlas ? # false si vous souhaitez utiliser celui de GeoNature en FDW # ATTENTION : Doit être true si geonature_source=false install_taxonomie=false @@ -122,12 +122,11 @@ altitudes=(0 500 1000 1500 2000 2500 3000 3500 4000) # Numéro de version conseillée et testée : 1.8.1 taxhub_release=1.8.1 -#### ID DES TYPES DES ATTRIBUTS DECRIVANT LES TAXONS DANS atlas.vm_cor_taxon_attribut -- +#### LISTE DES CODES DES TYPES DES ATTRIBUTS DÉCRIVANT LES TAXONS DANS atlas.vm_taxon_attribute ## !! si changement: modifier également dans main/configuration/config.py -attr_desc=100 -attr_commentaire=101 -attr_milieu=102 -attr_chorologie=103 +# Les codes correspondent aux valeurs du champs `taxonomie.bib_attributs.nom_attribut`. +# Les codes doivent être séparé par des virgules et placé entre guillemets simples. +displayed_attr="'atlas_description', 'atlas_commentaire', 'atlas_milieu', 'atlas_chorologie'" # Paramètre pour la vue atlas.vm_taxons_plus_observes # Especes les plus observées sur la periode 'moins X jour, plus X jours par rapport à la date du jour, toutes années confondues' diff --git a/atlas/modeles/repositories/vmCorTaxonAttribut.py b/atlas/modeles/repositories/vmCorTaxonAttribut.py index f5ef3234..87fec196 100644 --- a/atlas/modeles/repositories/vmCorTaxonAttribut.py +++ b/atlas/modeles/repositories/vmCorTaxonAttribut.py @@ -3,30 +3,16 @@ from sqlalchemy.sql import text -def getAttributesTaxon(connection, cd_ref, attrDesc, attrComment, attrMilieu, attrChoro): +def getAttributesTaxon(connection, cd_ref, displayed_attr): sql = """ SELECT * - FROM atlas.vm_cor_taxon_attribut - WHERE id_attribut IN (:thisattrDesc, :thisattrComment, :thisattrMilieu, :thisattrChoro) - AND cd_ref = :thiscdref + FROM atlas.vm_taxon_attribute + WHERE code = ANY(:displayedAttr) + AND cd_ref = :cdRef """ - req = connection.execute( - text(sql), - thiscdref=cd_ref, - thisattrDesc=attrDesc, - thisattrComment=attrComment, - thisattrMilieu=attrMilieu, - thisattrChoro=attrChoro, - ) + results = connection.execute(text(sql), displayedAttr=displayed_attr, cdRef=cd_ref) - descTaxon = {"description": None, "commentaire": None, "milieu": None, "chorologie": None} - for r in req: - if r.id_attribut == attrDesc: - descTaxon["description"] = r.valeur_attribut - elif r.id_attribut == attrComment: - descTaxon["commentaire"] = r.valeur_attribut - elif r.id_attribut == attrMilieu: - descTaxon["milieu"] = r.valeur_attribut.replace("&", " | ") - elif r.id_attribut == attrChoro: - descTaxon["chorologie"] = r.valeur_attribut - return descTaxon + desc_taxon = [] + for row in results: + desc_taxon.append({"code": row.code, "title": row.title, "value": row.value}) + return desc_taxon diff --git a/atlas/templates/speciesSheet/blocInfos.html b/atlas/templates/speciesSheet/blocInfos.html index 4dc7b1e7..15d4915f 100644 --- a/atlas/templates/speciesSheet/blocInfos.html +++ b/atlas/templates/speciesSheet/blocInfos.html @@ -1,67 +1,64 @@ {% block blocInfos %} -{% if configuration.GLOSSAIRE %} - - - - -{% endif %} + {% if configuration.GLOSSAIRE %} + + + + + {% endif %} -
-

- {{ _('species.infos') }} -

- +
+

+ {{ _('species.infos') }} +

+ -
-
- {% if taxonDescription.description == None %} - {{ _('not.resigned.for.the.moment') }} - {% else %} - {{ taxonDescription.description | safe }} - {% endif %} -
- {% if taxonDescription.commentaire != None %} -
- {{ taxonDescription.commentaire | safe }} -
- {% endif %} -
- {% if taxonDescription.milieu == None %} - {{ _('not.resigned.for.the.moment') }} - {% else %} - {{ taxonDescription.milieu }} - {% endif %} -
-
- {% if taxonDescription.chorologie == None %} - {{ _('not.resigned.for.the.moment') }} - {% else %} - {{ taxonDescription.chorologie }} - {% endif %} -
-
- {% if synonyme | length == 1 %} - {{ _('no.synonym.for.this.taxon') }} - {% else %} - {% for syn in synonyme %} - {% if not syn.lb_nom == taxon.taxonSearch.lb_nom %} - {{ syn.nom_complet_html | safe }} - {% endif %} - {% if ( (not loop.last) and (not syn.lb_nom == taxon.taxonSearch.lb_nom) ) %} - | - {% endif %} +
+ {% for desc in taxonDescription %} +
+ {% if desc.value == None %} + {{ _('not.resigned.for.the.moment') }} + {% else %} + {{ desc.value | safe }} + {% endif %} +
{% endfor %} - {% endif %} +
+ {% if synonyme | length == 1 %} + {{ _('no.synonym.for.this.taxon') }} + {% else %} + {% for syn in synonyme %} + {% if not syn.lb_nom == taxon.taxonSearch.lb_nom %} + {{ syn.nom_complet_html | safe }} + {% endif %} + {% if ( (not loop.last) and (not syn.lb_nom == taxon.taxonSearch.lb_nom) ) %} + | + {% endif %} + {% endfor %} + {% endif %} +
-
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/data/atlas/14.grant.sql b/data/atlas/14.grant.sql index 42e26451..10639bae 100644 --- a/data/atlas/14.grant.sql +++ b/data/atlas/14.grant.sql @@ -23,7 +23,7 @@ GRANT USAGE ON SCHEMA atlas TO my_reader_user; GRANT SELECT ON TABLE atlas.vm_altitudes TO my_reader_user; GRANT SELECT ON TABLE atlas.vm_communes TO my_reader_user; GRANT SELECT ON TABLE atlas.vm_observations TO my_reader_user; -GRANT SELECT ON TABLE atlas.vm_cor_taxon_attribut TO my_reader_user; +GRANT SELECT ON TABLE atlas.vm_taxon_attribute TO my_reader_user; GRANT SELECT ON TABLE atlas.vm_medias TO my_reader_user; GRANT SELECT ON TABLE atlas.vm_observations TO my_reader_user; GRANT SELECT ON TABLE atlas.vm_observations_mailles TO my_reader_user; diff --git a/data/atlas/9.atlas.vm_cor_taxon_attribut.sql b/data/atlas/9.atlas.vm_cor_taxon_attribut.sql deleted file mode 100644 index 97bf93f9..00000000 --- a/data/atlas/9.atlas.vm_cor_taxon_attribut.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Attributs de chaque taxon (description, commentaire, milieu et chorologie) -CREATE MATERIALIZED VIEW atlas.vm_cor_taxon_attribut AS - SELECT id_attribut, - valeur_attribut, - cd_ref - FROM taxonomie.cor_taxon_attribut - WHERE id_attribut IN (100, 101, 102, 103); -CREATE UNIQUE INDEX ON atlas.vm_cor_taxon_attribut (cd_ref,id_attribut); diff --git a/data/atlas/9.atlas.vm_taxon_attribute.sql b/data/atlas/9.atlas.vm_taxon_attribute.sql new file mode 100644 index 00000000..b3fa6e8a --- /dev/null +++ b/data/atlas/9.atlas.vm_taxon_attribute.sql @@ -0,0 +1,18 @@ +-- Attributs TaxHub de chaque taxon +CREATE MATERIALIZED VIEW atlas.vm_taxon_attribute AS + SELECT cta.cd_ref, + ba.nom_attribut AS code, + ba.label_attribut AS title, + CASE + WHEN ba.type_attribut = 'text' AND ba.type_widget = 'select' + THEN REPLACE(cta.valeur_attribut, '&', '|') + ELSE cta.valeur_attribut + END AS "value" + FROM taxonomie.cor_taxon_attribut AS cta + JOIN taxonomie.bib_attributs AS ba + ON cta.id_attribut = ba.id_attribut + WHERE ba.nom_attribut IN ('atlas_description', 'atlas_commentaire', 'atlas_milieu', 'atlas_chorologie') + AND cta.valeur_attribut IS NOT NULL + AND cta.valeur_attribut != '' ; + +CREATE UNIQUE INDEX ON atlas.vm_taxon_attribute (cd_ref, code); diff --git a/data/atlas/atlas.refresh_materialized_view_data.sql b/data/atlas/atlas.refresh_materialized_view_data.sql index 4e16e30f..09cc1b9b 100644 --- a/data/atlas/atlas.refresh_materialized_view_data.sql +++ b/data/atlas/atlas.refresh_materialized_view_data.sql @@ -31,7 +31,7 @@ BEGIN REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_altitudes; REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_taxons; - REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_cor_taxon_attribut; + REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_taxon_attribute; REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_search_taxon; REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_medias; REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_taxons_plus_observes; diff --git a/data/gn2/atlas_ref_taxonomie.sql b/data/gn2/atlas_ref_taxonomie.sql index fdc5df16..d25b2380 100644 --- a/data/gn2/atlas_ref_taxonomie.sql +++ b/data/gn2/atlas_ref_taxonomie.sql @@ -7,12 +7,15 @@ CREATE SCHEMA IF NOT EXISTS taxonomie; IMPORT FOREIGN SCHEMA taxonomie -LIMIT TO (taxonomie.taxref, taxonomie.cor_taxon_attribut, taxonomie.t_medias) +LIMIT TO (taxonomie.taxref, taxonomie.bib_attributs, taxonomie.cor_taxon_attribut, taxonomie.t_medias) FROM SERVER geonaturedbserver INTO taxonomie ; ALTER TABLE taxonomie.taxref OWNER TO myuser; GRANT ALL ON TABLE taxonomie.taxref TO myuser; +ALTER TABLE taxonomie.bib_attributs OWNER TO myuser; +GRANT ALL ON TABLE taxonomie.bib_attributs TO myuser; + ALTER TABLE taxonomie.cor_taxon_attribut OWNER TO myuser; GRANT ALL ON TABLE taxonomie.cor_taxon_attribut TO myuser; diff --git a/data/update/update_attribute.sql b/data/update/update_attribute.sql new file mode 100644 index 00000000..ad5cd262 --- /dev/null +++ b/data/update/update_attribute.sql @@ -0,0 +1,63 @@ +BEGIN; + +DROP MATERIALIZED VIEW IF EXISTS atlas.vm_taxon_attribute ; + +DROP FOREIGN TABLE IF EXISTS taxonomie.bib_attributs ; + +DROP MATERIALIZED VIEW IF EXISTS atlas.vm_cor_taxon_attribut ; + +IMPORT FOREIGN SCHEMA taxonomie +LIMIT TO (taxonomie.bib_attributs) +FROM SERVER geonaturedbserver INTO taxonomie ; + +ALTER TABLE taxonomie.bib_attributs OWNER TO geonatatlas; +GRANT ALL ON TABLE taxonomie.bib_attributs TO geonatatlas; + +CREATE MATERIALIZED VIEW atlas.vm_taxon_attribute AS + SELECT cta.cd_ref, + ba.nom_attribut AS code, + ba.label_attribut AS title, + CASE + WHEN ba.type_attribut = 'text' AND ba.type_widget = 'select' + THEN REPLACE(cta.valeur_attribut, '&', '|') + ELSE cta.valeur_attribut + END AS "value" + FROM taxonomie.cor_taxon_attribut AS cta + JOIN taxonomie.bib_attributs AS ba + ON cta.id_attribut = ba.id_attribut + WHERE ba.nom_attribut IN ('atlas_description', 'atlas_commentaire', 'atlas_milieu', 'atlas_chorologie') + AND cta.valeur_attribut IS NOT NULL + AND cta.valeur_attribut != '' ; + +CREATE UNIQUE INDEX ON atlas.vm_taxon_attribute (cd_ref, code); + + +ALTER MATERIALIZED VIEW atlas.vm_taxon_attribute OWNER TO geonatatlas; +GRANT SELECT ON TABLE atlas.vm_taxon_attribute TO geonatatlas; + + +CREATE OR REPLACE FUNCTION atlas.refresh_materialized_view_data() +RETURNS VOID AS $$ +BEGIN + + REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_observations; + REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_observations_mailles; + REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_mois; + + REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_altitudes; + + REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_taxons; + REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_taxon_attribute; + REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_search_taxon; + REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_medias; + REFRESH MATERIALIZED VIEW CONCURRENTLY atlas.vm_taxons_plus_observes; + +END +$$ LANGUAGE plpgsql; + + +-- TODO: adapt taxonomie.bib_attributs owner if it's not default "geonatatlas" +-- TOOD: adapt if necessary "ba.nom_attribut IN ('atlas_description', 'atlas_commentaire', 'atlas_milieu', 'atlas_chorologie')" + + +COMMIT; diff --git a/docs/vues_materialisees_maj.rst b/docs/vues_materialisees_maj.rst index 9c85bc27..24754252 100644 --- a/docs/vues_materialisees_maj.rst +++ b/docs/vues_materialisees_maj.rst @@ -54,7 +54,7 @@ Les champs de cette table sont ``cd_nom``, ``id_statut``, ``id_habitat``, ``id_r - ``atlas.vm_medias`` qui renvoie tous les médias des taxons, sur la base du schéma ``taxonomie`` de TaxHub -- ``atlas.vm_cor_taxon_attribut`` qui renvoie les 4 descriptions des taxons (description, commentaire, milieux, chorologie, sur la base du schéma ``taxonomie`` de TaxHub +- ``atlas.vm_taxon_attribute`` qui renvoie les attributs TaxHub des taxons. Par défaut : description, commentaire, milieux, chorologie, sur la base du schéma ``taxonomie`` de TaxHub. - ``atlas.vm_observations_mailles`` qui renvoie la liste de toute les observations agrégées par maille. @@ -159,6 +159,6 @@ Ajouter la ligne suivante en prenant soin de mettre à jour les paramètres de c Pour enregistrer et sortir : ``Ctrl + O``, ENTER puis ``Ctrl + X`` -Cette fonction rafraichit toutes les vues materialisées présentes dans le schéma ``atlas`` et ne tient pas compte de l'ordre du rafraichissement. Cette opération peut-être assez longue dans le cas où le réferentiel géographique est volumineux alors que celui-ci est relativement stable (peu de MAJ des communes ou du territoire). +Cette fonction rafraichit toutes les vues materialisées présentes dans le schéma ``atlas`` et ne tient pas compte de l'ordre du rafraichissement. Cette opération peut-être assez longue dans le cas où le réferentiel géographique est volumineux alors que celui-ci est relativement stable (peu de MAJ des communes ou du territoire). Dans ce cas, préferez un rafraichisement automatique uniquement des données : fonction ``atlas.refresh_materialized_view_data()``. Pour rafraichir les données géographiques, lancer ponctuellement la fonction ``atlas.refresh_materialized_view_ref_geo()``. diff --git a/install_db.sh b/install_db.sh index 5df6990a..e69d9485 100755 --- a/install_db.sh +++ b/install_db.sh @@ -389,10 +389,10 @@ if ! database_exists $db_name export PGPASSWORD=$owner_atlas_pass;psql -d $db_name -U $owner_atlas -h $db_host -p $db_port -f /tmp/atlas/8.atlas.vm_medias.sql &>> log/install_db.log echo "[$(date +'%H:%M:%S')] Passed - Duration : $((($SECONDS-$time_temp)/60))m$((($SECONDS-$time_temp)%60))s" - echo "[$(date +'%H:%M:%S')] Creating atlas.vm_cor_taxon_attribut..." + echo "[$(date +'%H:%M:%S')] Creating atlas.vm_taxon_attribute..." time_temp=$SECONDS - sudo sed -i "s/WHERE id_attribut IN (100, 101, 102, 103);$/WHERE id_attribut IN ($attr_desc, $attr_commentaire, $attr_milieu, $attr_chorologie);/" /tmp/atlas/9.atlas.vm_cor_taxon_attribut.sql - export PGPASSWORD=$owner_atlas_pass;psql -d $db_name -U $owner_atlas -h $db_host -p $db_port -f /tmp/atlas/9.atlas.vm_cor_taxon_attribut.sql &>> log/install_db.log + sudo sed -i "s/WHERE id_attribut IN ('atlas_description', 'atlas_commentaire', 'atlas_milieu', 'atlas_chorologie')$/WHERE id_attribut IN ($displayed_attr);/" /tmp/atlas/9.atlas.vm_taxon_attribute.sql + export PGPASSWORD=$owner_atlas_pass;psql -d $db_name -U $owner_atlas -h $db_host -f /tmp/atlas/9.atlas.vm_taxon_attribute.sql &>> log/install_db.log echo "[$(date +'%H:%M:%S')] Passed - Duration : $((($SECONDS-$time_temp)/60))m$((($SECONDS-$time_temp)%60))s" echo "[$(date +'%H:%M:%S')] Creating atlas.vm_taxons_plus_observes..."