MTES-MCT / metadata-postgresql

Plume : gestion des métadonnées du patrimoine PostgreSQL
https://mtes-mct.github.io/metadata-postgresql/
GNU Affero General Public License v3.0
0 stars 1 forks source link

Codes invalides dans les valeurs du paramètre `langList` #174

Closed alhyss closed 7 months ago

alhyss commented 8 months ago

Je viens d'écrire dans la documentation utilisateur que les codes de langues listés dans le paramètre utilisateur Langues autorisées pour les traductions / langList devaient être séparés par des virgules sans aucun espace, mais - puisque tout le monde n'applique pas à la lettre les recommandations de la documentation - j'ai peur que ce soit une source d'erreur.

Actuellement les espaces saisis sont préservés. Or un code de langue contenant un espace n'est pas un code valide, et cela a même pour effet de provoquer des erreurs non gérées.

Par exemple, si je saisis la liste "fr,en, it", Plume considère trois codes de langues "fr", "en" et " it" avec un espace. Si, en mode traduction, je sélectionne ce dernier comme langue de saisie d'une valeur textuelle et que je tente de sauvegarder la fiche de métadonnées, l'erreur suivante est renvoyée :

Traceback (most recent call last):
  File "C:\Users/alhyss/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\plume\plume_ui.py", line 64, in safe_pg_connection
    yield
  File "C:\Users/alhyss/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\plume\plume_ui.py", line 353, in clickButtonsActions
    saveMetaIhm(self, self.schema, self.table)
  File "C:\Users/alhyss/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\plume\bibli_plume.py", line 625, in saveMetaIhm
    self.mDicObjetsInstancies.update_value(_keyObjet, value)
  File "C:\Users/alhyss/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\plume\rdf\widgetsdict.py", line 1427, in update_value
    widgetkey.value = self.prepare_value(widgetkey, value)
  File "C:\Users/alhyss/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\plume\rdf\widgetsdict.py", line 1364, in prepare_value
    return Literal(str(value), lang=widgetkey.value_language)
  File "C:\Users\alhyss\AppData\Roaming\Python\Python39\site-packages\rdflib\term.py", line 625, in __new__
    raise ValueError(f"'{str(lang)}' is not a valid language tag!")
ValueError: ' it' is not a valid language tag!

Au delà des espaces, RDFLib utilise l'expression régulière "^[a-zA-Z]+(?:-[a-zA-Z0-9]+)*$" pour tester la validité des codes de langue, et émet une erreur lorsque le test échoue. La référence en la matière est BCP 47 (ou plus précisément la section 2.2.9 de RFC 5646).

Je pense qu'il faut agir à trois niveaux :

  1. @WREATCHED Supprimer automatiquement les espaces saisis par mégarde.
  2. @WREATCHED Empêcher l'utilisateur de saisir pour langList des valeurs qui ne respectent pas l'expression régulière "^[a-zA-Z]+(?:-[a-zA-Z0-9]+)*$".
  3. @alhyss Pour les codes de langues invalides qui passeraient entre les mailles du filet (par exemple un code issu d'un import ?), ajouter un contrôle dans plume.rdf.widgetsdict.WidgetsDict.prepare_value. Actuellement, cette méthode élimine silencieusement toutes les valeurs invalides.

Le point 3 suffit en lui-même à faire disparaître l'anomalie, il est dès lors prioritaire. 1 et 2 constituent une petite évolution peu urgente pour limiter les cas où l'utilisateur se retrouve avec des valeurs éliminées sans aucune explication ni avertissement parce qu'il a mal saisi un code de langue dans ses paramètres.

alhyss commented 8 months ago

@WREATCHED Les modifications que je viens de faire répondent au point 3. Plus de bug, donc. Maintenant si l'utilisateur écrit par mégarde "fr,en, it", toutes les valeurs auxquelles la langue " it" est associée vont simplement disparaître sans avertissement à chaque enregistrement. Je te laisse voir comment tu veux gérer ça - points 1 et 2 ci-avant ou autre solution qui te convient mieux.

Dans tous les cas, si tu mets en place un contrôle des codes de langue saisis dans la boîte de dialogue de personnalisation de l'interface. tu pourras réutiliser la constante que j'ai définie pour l'expression régulière : plume.rdf.utils.LANGUAGE_REG.

https://github.com/MTES-MCT/metadata-postgresql/blob/9a14a5fa8bbd3a3031ae73ff3bc4e7cdf036877b/plume/rdf/utils.py#L78

WREATCHED commented 8 months ago

Corrections

alhyss commented 8 months ago

La déclinaison de l'expression régulière initiale pour une liste de codes séparés par des virgules, ce serait plutôt ça :

'^[a-zA-Z]+(?:-[a-zA-Z0-9]+)*(?:,[a-zA-Z]+(?:-[a-zA-Z0-9]+)*)*$'

Elle est moins restrictive que la tienne.

WREATCHED commented 8 months ago

1) pour le Widget

        #- Validation de la zone de saisie
        regLangList = '^[a-zA-Z]+(?:-[a-zA-Z0-9]+)*(?:,[a-zA-Z]+(?:-[a-zA-Z0-9]+)*)*$'
        QRegExp     = QRegularExpression( regLangList )
        validator   = QRegularExpressionValidator( QRegExp, mZoneLangList )
        mZoneLangList.setValidator(validator)

2) pour la validation et l'écriture dans le Qgis3.ini

        # 1) Enlever les espaces
        mDicUserSettings["langList"] = [ elem.strip(" -") for elem in self.mZoneLangList.text().split(",") if elem.strip() != "" ]   
        self.mZoneLangList.setText(",".join(mDicUserSettings["langList"]))