Skip to content
This repository has been archived by the owner on Jun 3, 2020. It is now read-only.

Cannot configure Builder menu in the global_settings.ini file #6

Open
FERRATON opened this issue May 14, 2019 · 2 comments
Open

Cannot configure Builder menu in the global_settings.ini file #6

FERRATON opened this issue May 14, 2019 · 2 comments

Comments

@FERRATON
Copy link

Pour aller plus vite je décris le pb en français...
Avec QGIS 3.4 il est maintenant possible de lancer une instance de QGIS pointant vers un fichier global_settings de service (option --globalsettingsfile).
On souhaiterait pouvoir pré-paramétrer l'ensemble des postes utilisateurs avec un menu issu de Menu Builder en recopiant les sections de paramètres du QGIS3.ini en utilisation standard dans le fichier global_settings.ini du service.
exemple :
#connexion à postgreSQL
[PostgreSQL]
connections\formation\sslmode=SslDisable
connections\selected=formation
connections\formation\service=
connections\formation\host=localhost
connections\formation\port=5432
connections\formation\database=formationsql
connections\formation\username=postgres
connections\formation\password=admin
connections\formation\authcfg=
connections\formation\publicOnly=false
connections\formation\geometryColumnsOnly=false
connections\formation\dontResolveType=false
connections\formation\allowGeometrylessTables=false
connections\formation\saveUsername=true
connections\formation\savePassword=true
connections\formation\estimatedMetadata=false
connections\formation\projectsInDatabase=false

#paramètres de MenuBuilder
[MenuBuilder]
database=formation
schema=public
profile=test
dock=false
menubar=true

#activation de MenuBuilder
[PythonPlugins]
MenuBuilder=true

#Chargement de Menu Builder par désignation d'un chemin de plugin complémentaires
[qgis]
customEnvVars="overwrite|OGR_ODS_HEADERS=FORCE", "overwrite|OGR_XLS_HEADER=FORCE", "overwrite|OGR_XLSX_HEADER=FORCE", "overwrite|QGIS_PLUGINPATH=T:\plugin qgis\plugins"

Hors bien que les paramètres soient bien lus (on peut le vérifier en allant dans les options de QGIS, onglet avancé, au 1er lancement de QGIS après installation et en repartant d'un profil vierge (donc sans encore de fichier QGIS3.ini créé). Le menu ne se charge pas (le restore_session ne se fait pas).
Si on lance menu Builder il ne détecte pas la connexion à la base de données.
Peut-être parce que MenuBuilder est chargé au mauvais moment et/ou ne rafraichit pas sa liste de connections ?

Cordialement,

@FERRATON
Copy link
Author

Un développeur en interne a identifié le pb. Il vient de l'utilisation de QSettings (PyQT5.core) au lieu de QgsSettings (QGIS.core). QgsSettings étant basée sur
QSettings (en fait, cette classe utilise deux instances QSettings, une pour
les User Settings, l'autre pour les Global Settings), elle autorise
les mêmes méthodes et il suffit ici de subsituer QgsSettings à QSettings.
Il faut donc ligne 222 :
settings = QgsSettings()
# au lieu de :
settings = QSettings()
et ajouter QGSSettings dans la liste des modules à importer.

lignes 37 à 40 modifiées

from qgis.core import (
QgsProject, QgsBrowserModel, QgsDataSourceUri, QgsSettings,
QgsCredentials, QgsVectorLayer, QgsMimeDataUtils, QgsRasterLayer
)

au lieu de :

from qgis.core import (
QgsProject, QgsBrowserModel, QgsDataSourceUri,
QgsCredentials, QgsVectorLayer, QgsMimeDataUtils, QgsRasterLayer
)

Autres propositions de corrections;

Possibilité que qgis_menubuilder_metadata soit une vue ;
à partir de la ligne 371 :

            union
            select 1
            from pg_views
                where schemaname = '{0}'
                and viewname = '{1}'

(avant ça, il y a l'union de deux requêtes
similaires qui récupèrent l'une la liste des
tables et l'autres la liste des vues matérialisées)

MenuBuilder ne tient pas compte du paramètre sslmode. Il faut modifier la ligne 237:
# ligne 237 modifiée (SslPrefer est la valeur par défaut)
sslmode = settings.enumValue("sslmode", uri.SslPrefer)

Corrections de pb avec les connexions :

(1) QGIS mémorise temporairement les couples identifiant/mot de passe au
cours d'une session pour éviter à l'utilisateur de les resaisir à
chaque requête. Non seulement MenuBuilder ne garde lui-même rien en
mémoire, mais il suffit qu'il ouvre une connexion pour que les éventuels
identifiant/mot de passe préalablement mémorisés par QGIS ne soient
plus accessibles à QGIS lui-même (l'utilisateur devra donc les resaisir) ;
(2) MenuBuilder laisse certaines de ses connexions ouvertes (jusqu'à la
fermeture de QGIS) alors qu'elles ne servent absolument plus à rien ;
(3) si l'utilisateur fait une erreur dans son mot de passe ou son identifiant,
le lancement du plugin échoue et il se trouve contraint de relancer QGIS pour
afficher le menu - il paraîtrait nettement préférable de le laisser réessayer.

[1) Le premier défaut vient du fait que MenuBuilder récupère l'identifiant et
le mot de passe via QgsCredentials.instance().get - ce qui a pour effet,
le cas échéant, de supprimer les valeurs préalablement stockées par
QGIS dans instance() - sans lancer par la suite un QgsCredentials.instance().put
pour restocker les valeurs.

Il suffit donc d'ajouter une ligne pour que l'utilisateur n'ait à saisir
qu'une fois pour toutes son identifiant et son mot de passe - en l'occurrence
à l'ouverture de QGIS, lorsque MenuBuilder regénère le menu.

        # ajout de la ligne 327
        QgsCredentials.instance().put(conninfo, username, password)

(2) Concernant les connexions ouvertes, il y a visiblement deux cas : lors de la
restauration du menu à l'ouverture et lorsqu'on sort de l'interface
de paramétrage de MenuBuilder en cliquant sur "Appliquer". A priori,
on doit pouvoir régler ça en ajoutant self.close_connection() aux lignes
720 et 761.

Accessoirement, pour pouvoir suivre plus facilement les connexions
de MenuBuilder via PgAdmin, on peut ajouter un nom d'application dans
le connexion string :

        # lignes 310 et 326
        self.connection = psycopg2.connect(uri.connectionInfo(), application_name="QGIS:MenuBuilder")
        # au lieu de :
        self.connection = psycopg2.connect(uri.connectionInfo())

(3) Faire en sorte que l'utilisateur se voit redemander son mot
de passe en cas d'échec requiert juste une boucle while. La modification
n'est pas bien lourde en elle-même, mais elle nécessite de déplacer
quelques commandes pour assurer que toutes les variables soient bien
définies lorsqu'elles sont appelées.

    # les lignes 309 à 331 sont remplacées par :
    
    conninfo = uri.connectionInfo()

    while True:
        try:
            self.connection = psycopg2.connect(uri.connectionInfo(), application_name="QGIS:MenuBuilder")
            break
        except self.pg_error_types() as e:
            err = str(e) or "Erreur d'authentification. Vérifiez les informations saisies."
                            
            ok, username, password = QgsCredentials.instance().get(
                conninfo, username, password, err)
            if not ok:
                raise e
            if username:
                uri.setUsername(username)
            if password:
                uri.setPassword(password)
    
    QgsCredentials.instance().put(conninfo, username, password) 
    
    self.pgencoding = self.connection.encoding

    return True


    # au lieu de (en prenant déjà en compte les modifications précédemment évoquées) :
    
    try:
        self.connection = psycopg2.connect(uri.connectionInfo(), application_name="QGIS:MenuBuilder")
    except self.pg_error_types() as e:
        err = e
        conninfo = uri.connectionInfo()
        
        ok, username, password = QgsCredentials.instance().get(
            conninfo, username, password, str(err))
        if not ok:
            raise e

        if username:
            uri.setUsername(username)

        if password:
            uri.setPassword(password)

        self.connection = psycopg2.connect(uri.connectionInfo(), application_name="QGIS:MenuBuilder")
        QgsCredentials.instance().put(conninfo, username, password)            

    self.pgencoding = self.connection.encoding

    return True

NB : "err = str(e) or "Erreur d'authentification. Vérifiez les informations saisies.""
sert à afficher un message dans la boîte de dialogue lorsque
la tentative de connexion précédente a échoué non parce
qu'il manque un nom d'utilisateur ou un mot de passe
mais parce que ceux qui ont été fournis sont invalides
(car PostgreSQL ne renvoie pas de descriptif
d'erreur dans ce cas).

En PJ le fichier modifié (changer .txt en .py)
menu_builder_dialog.txt
.

@SebastienPeillet
Copy link

Project migrated to : https://gitlab.com/Oslandia/qgis/qgis-menu-builder

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants