Compare commits

..
31 Commits
Author SHA1 Message Date
tlaveille e23b9e80c0 Option authentification pour table avec droits particuliers. 2026-05-22 15:05:31 +02:00
tlaveille 5fd101543e maj 1.42 2026-05-21 09:08:12 +02:00
tlaveille def79fdaa9 Performance optimisée hors connexion 2026-05-21 08:36:37 +02:00
tlaveille eae3a80f31 maj 1.41 2026-05-04 11:57:50 +02:00
tlaveille 61ed7b286a delete n2000 old logo 2026-05-04 11:27:25 +02:00
tlaveille 4a3d0a38c3 rollback 2026-04-22 12:11:34 +02:00
tlaveille 1185a7313d test 2026-04-22 12:11:07 +02:00
tlaveille d844b9d416 add ok/close to change log 2026-03-27 13:56:27 +01:00
tlaveille 5200a3b3c2 maj 1.40 2026-03-23 11:33:59 +01:00
tlaveille 8c8068b330 Désactivation qu'en hors connexion pour accélérer QGIS. 2026-03-23 11:30:41 +01:00
tlaveille 8a1e7e6d70 fix bug entre q4 et les logo/icon 2026-03-20 11:47:02 +01:00
tlaveille 2765093f1d 100% flake8 compatible 2026-03-19 08:59:07 +01:00
tlaveille 614195fbaf maj all plugin qgis 4.0 2026-03-12 16:12:00 +01:00
tlaveille ebeefb78b9 qgisMaximumVersion = 4.99 2026-03-12 09:06:45 +01:00
tlaveille 256a0ac6d4 maj flux 3.20 2026-03-05 11:42:17 +01:00
tlaveille af10bce94c nom de la variable XML 2026-03-05 11:34:24 +01:00
tlaveille 8c55d902c0 lecture des description dans un tooltip 2026-03-05 10:09:58 +01:00
tlaveille 5a03084daa ouverture des couche flage 00 2026-02-26 15:14:49 +01:00
tlaveille a3b634d514 maj flux 3.19 2026-02-26 14:22:25 +01:00
tlaveille 728f72cffd visualisation des droit des vue et vue materialiser 2026-02-26 11:59:33 +01:00
tlaveille 272b47a174 maj flux 3.18 2026-02-25 11:26:50 +01:00
tlaveille 21a652fdb2 filtre par localisation bug fix 2026-02-25 11:13:35 +01:00
tlaveille 799a635edc mise à jour et ajoue de tool tip. 2026-02-13 15:10:07 +01:00
tlaveille ff2e0f22be commant 2026-02-12 11:41:59 +01:00
tlaveille 8c1ee42080 kill des connection postgresql 2026-02-12 11:05:14 +01:00
tlaveille a3479085b6 system de favorit 2026-02-12 10:04:28 +01:00
tlaveille 1b54026a13 system de favorit 2026-02-11 14:15:22 +01:00
tlaveille 670c698b77 Fix de bug et optimisation d'exécution. 2026-02-10 10:17:45 +01:00
tlaveille 9b438f5bf1 repaire git flux 2026-01-14 14:05:14 +01:00
tlaveille 02681490f6 Repaire 2026-01-09 11:16:56 +01:00
tlaveille 4b8bc74386 test de push 2026-01-09 10:25:55 +01:00
73 changed files with 6282 additions and 750 deletions
+11 -7
View File
@@ -4,7 +4,8 @@ __email__ = "info@3liz.org"
from qgis.core import QgsApplication
from qgis.PyQt.QtCore import Qt, QUrl
from qgis.PyQt.QtCore import QUrl
# from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtGui import QDesktopServices, QIcon
from qgis.PyQt.QtWidgets import QAction
from qgis.utils import iface
@@ -34,8 +35,11 @@ from .tools.resources import (
)
pyperclip()
from .canvas_editor import AutoMap_Editor
from .style_invoke import AutoMap_Style
try:
from .canvas_editor import AutoMap_Editor
# from .style_invoke import AutoMap_Style
except NameError:
print('404')
class PgAutoMap:
@@ -82,11 +86,11 @@ class PgAutoMap:
self.toolBar.addAction(self.automap_action)
self.automap_action.triggered.connect(self.open_editor)
if not self.style_dock:
self.style_dock = AutoMap_Style()
# if not self.style_dock:
# self.style_dock = AutoMap_Style()
if os.environ['USERNAME'] == 'tlaveille' or os.environ['USERNAME'] == 'lpoulin' or os.environ['USERNAME'] == 'rclement':
iface.addDockWidget(Qt.DockWidgetArea(0x1), self.style_dock)
# if os.environ['USERNAME'] == 'tlaveille' or os.environ['USERNAME'] == 'lpoulin' or os.environ['USERNAME'] == 'rclement':
# iface.addDockWidget(Qt.DockWidgetArea(0x1), self.style_dock)
def open_about_dialog(self):
"""
+3 -2
View File
@@ -5,9 +5,10 @@
[general]
name=CenRa_AutoMap
qgisMinimumVersion=3.0
qgisMaximumVersion=4.99
supportsQt6=True
description=CenRa_AutoMap
version=2.7
version=2.11
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
@@ -22,7 +23,7 @@ tracker=https://gitea.cenra-outils.org/api/v1/repos/CEN-RA/Plugin_QGIS/issues
hasProcessingProvider=no
# Uncomment the following line and add your changelog:
changelog=<h2>CenRa_AUTOMAP:</h2></br><p><h3>18/12/2025 - Version 2.7: </h3> - fix de bug gitea.</p></br><p><h3>18/12/2025 - Version 2.6: </h3> - ajoue du logo n2000 et region.</p></br><p><h3>17/12/2025 - Version 2.5: </h3> - Carte n2000 mise a jour landscape et portrait.</p></br><p><h3>15/12/2025 - Version 2.4: </h3> - Landescape pour n2000.</p></br><p><h3>15/12/2025 - Version 2.3: </h3> - nouvelle mise en page n2000.</p></br><p><h3>12/12/2025 - Version 2.2: </h3> - nouvelle mise en page pour n2000.</p></br><p><h3>30/07/2025 - Version 2.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 2.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>11/04/2025 - Version 1.7: </h3> - Correctif d'orthographe.</p></br><p><h3>09/04/2025 - Version 1.6: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 1.5: </h3> - Optimisation pour le TT.</p></br><p><h3>03/04/2025 - Version 1.4: </h3> - Mise a jour de securite.</p></br><p><h3>20/03/2025 - Version 1.3: </h3> - Fenêtre redimensionnable avec déplaçable avec la mollette sourit.</p></br><p><h3>25/02/2025 - Version 1.2: </h3> - DockWidget pour ouverture de couche avec theme.</p></br><p><h3>28/01/2025 - Version 1.1: </h3> - Multi-Composeur pris en charge.</p></br><p><h3>27/01/2025 - Version 1.0: </h3> - Version releases.</br> - Ajoute un message d'avertissement au moment d'écraser la mise en page.</br> - Ajoute prénom et nom dans la réalisation.</br> - Utilisation de Calibri.</p></br><p><h3>13/01/2025 - Version 0.1.10: </h3> - Correctif.</p></br><p><h3>07/01/2025 - Version 0.1.9: </h3> - ByPass du certif ssl ci erreur.</p></br><p><h3>19/12/2024 - Version 0.1.8: </h3> - Nouvelle mise en page.</br> - Incrémentation automatique de nouveau modele de mise en page. </br> - Correctif de bug.</p></br><p><h3>21/10/2024 - Version 0.1.7: </h3> - Epurations du code.</p></br><p><h3>07/10/2024 - Version 0.1.6: </h3> - Option de bibliotheque de logo custome.</p></br><p><h3>03/10/2024 - Version 0.1.5: </h3> - Remonte la fênetre dans la pille.</br> - Gestion du nombre de colonne dans la légend.</br></p></br><p><h3>02/10/2024 - Version 0.1.4: </h3> - Mise en page plein écrant.</br></p></br><p><h3>01/10/2024 - Version 0.1.3: </h3> - Récupération du titre et sous-titre pour mise en page existente.</br> - Integration de bibliotheque de logo.</br> - Integration de gestionaire pour les source de donnée.</br> - Mise en place d'une bar d'echelle adaptative. </br></p></br><p><h3>30/09/2024 - Version 0.1.2: </h3> - Activation du thème. </br> - Ajouter une carte de suivie. </br><p></br><h3>27/09/2024 - Version 0.1.1: </h3> - Ajout d'une liste déroulante pour les sources de données. </br>- Bouton pour ajouter des fonts de carte customisés. </br>- Fonctionnalité de génération d'atlas. </p></br><p><h3>26/09/2024 - Version 0.1.0: </h3> - Lancement du plugin CenRa_AutoMap avec une seul mise en page. </p></br>
changelog=<h2>CenRa_AUTOMAP:</h2></br><p><h3>21/05/2026 - Version 2.11: </h3> - Optimisation des performances hors connexion.</br></p></br><p><h3>04/05/2026 - Version 2.10: </h3> - Suppression ancien logo n2000.</p></br><p><h3>12/03/2026 - Version 2.9: </h3> - qgisMaximumVersion est 4.0.</p></br><p><h3>09/01/2026 - Version 2.8: </h3> - deplacement de l'echelle.</p></br><p><h3>18/12/2025 - Version 2.7: </h3> - fix de bug gitea.</p></br><p><h3>18/12/2025 - Version 2.6: </h3> - ajoue du logo n2000 et region.</p></br><p><h3>17/12/2025 - Version 2.5: </h3> - Carte n2000 mise a jour landscape et portrait.</p></br><p><h3>15/12/2025 - Version 2.4: </h3> - Landescape pour n2000.</p></br><p><h3>15/12/2025 - Version 2.3: </h3> - nouvelle mise en page n2000.</p></br><p><h3>12/12/2025 - Version 2.2: </h3> - nouvelle mise en page pour n2000.</p></br><p><h3>30/07/2025 - Version 2.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 2.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>11/04/2025 - Version 1.7: </h3> - Correctif d'orthographe.</p></br><p><h3>09/04/2025 - Version 1.6: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 1.5: </h3> - Optimisation pour le TT.</p></br><p><h3>03/04/2025 - Version 1.4: </h3> - Mise a jour de securite.</p></br><p><h3>20/03/2025 - Version 1.3: </h3> - Fenêtre redimensionnable avec déplaçable avec la mollette sourit.</p></br><p><h3>25/02/2025 - Version 1.2: </h3> - DockWidget pour ouverture de couche avec theme.</p></br><p><h3>28/01/2025 - Version 1.1: </h3> - Multi-Composeur pris en charge.</p></br><p><h3>27/01/2025 - Version 1.0: </h3> - Version releases.</br> - Ajoute un message d'avertissement au moment d'écraser la mise en page.</br> - Ajoute prénom et nom dans la réalisation.</br> - Utilisation de Calibri.</p></br><p><h3>13/01/2025 - Version 0.1.10: </h3> - Correctif.</p></br><p><h3>07/01/2025 - Version 0.1.9: </h3> - ByPass du certif ssl ci erreur.</p></br><p><h3>19/12/2024 - Version 0.1.8: </h3> - Nouvelle mise en page.</br> - Incrémentation automatique de nouveau modele de mise en page. </br> - Correctif de bug.</p></br><p><h3>21/10/2024 - Version 0.1.7: </h3> - Epurations du code.</p></br><p><h3>07/10/2024 - Version 0.1.6: </h3> - Option de bibliotheque de logo custome.</p></br><p><h3>03/10/2024 - Version 0.1.5: </h3> - Remonte la fênetre dans la pille.</br> - Gestion du nombre de colonne dans la légend.</br></p></br><p><h3>02/10/2024 - Version 0.1.4: </h3> - Mise en page plein écrant.</br></p></br><p><h3>01/10/2024 - Version 0.1.3: </h3> - Récupération du titre et sous-titre pour mise en page existente.</br> - Integration de bibliotheque de logo.</br> - Integration de gestionaire pour les source de donnée.</br> - Mise en place d'une bar d'echelle adaptative. </br></p></br><p><h3>30/09/2024 - Version 0.1.2: </h3> - Activation du thème. </br> - Ajouter une carte de suivie. </br><p></br><h3>27/09/2024 - Version 0.1.1: </h3> - Ajout d'une liste déroulante pour les sources de données. </br>- Bouton pour ajouter des fonts de carte customisés. </br>- Fonctionnalité de génération d'atlas. </p></br><p><h3>26/09/2024 - Version 0.1.0: </h3> - Lancement du plugin CenRa_AutoMap avec une seul mise en page. </p></br>
# Tags are comma separated with spaces allowed
tags=python
Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

+5 -1
View File
@@ -21,7 +21,11 @@ from .tools.resources import (
maj_verif,
)
pyperclip()
from .copie_editor import Copie_Editor
try:
from .copie_editor import Copie_Editor
except NameError:
print('404')
class PgCopie:
+3 -2
View File
@@ -9,9 +9,10 @@
[general]
name=CenRA_COPIE
qgisMinimumVersion=3.0
qgisMaximumVersion=4.99
supportsQt6=True
description=Permet la copie d'une table dans une base PostGis
version=3.1
version=3.2
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
@@ -20,7 +21,7 @@ email=si_besoin@cen-rhonealpes.fr
# Recommended items:
# Uncomment the following line and add your changelog:
changelog=<h2>CenRa_COPIE:</h2></br><p><h3>30/07/2025 - Version 3.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 3.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>11/04/2025 - Version 2.5: </h3> - Correctif de bug.</p></br><p><h3>09/04/2025 - Version 2.4: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 2.3: </h3> - Optimisation pour le TT.</p></br><p><h3>03/04/2025 - Version 2.2: </h3> - Mise a jour de securite.</p></br><p><h3>07/01/2025 - Version 2.1: </h3> - ByPass du certif ssl ci erreur.</br></p><p><h3>22/10/2024 - Version 2:</h3>- Refonte du code.</p></br><p><h3>13/09/2024 - Version 1.5:</h3>- Ajoute d'un changelog et vérification de mise à jour.</p>
changelog=<h2>CenRa_COPIE:</h2></br><p><h3>12/03/2026 - Version 3.2: </h3> - qgisMaximumVersion est 4.0.</p></br><p><h3>30/07/2025 - Version 3.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 3.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>11/04/2025 - Version 2.5: </h3> - Correctif de bug.</p></br><p><h3>09/04/2025 - Version 2.4: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 2.3: </h3> - Optimisation pour le TT.</p></br><p><h3>03/04/2025 - Version 2.2: </h3> - Mise a jour de securite.</p></br><p><h3>07/01/2025 - Version 2.1: </h3> - ByPass du certif ssl ci erreur.</br></p><p><h3>22/10/2024 - Version 2:</h3>- Refonte du code.</p></br><p><h3>13/09/2024 - Version 1.5:</h3>- Ajoute d'un changelog et vérification de mise à jour.</p>
# Tags are comma separated with spaces allowed
tags=cenra, database, table
+3 -7
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CenRa_Metabase_editorwidget_base</class>
<widget class="QDialog" name="CenRa_Metabase_editorwidget_base">
<widget class="QDialog" name="CenRa_about_base">
<property name="geometry">
<rect>
<x>0</x>
@@ -13,10 +13,6 @@
<property name="windowTitle">
<string>Journal des modifications</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>../../CenRa_Metabase/tools/ui/icon.svg</normaloff>../../CenRa_Metabase/tools/ui/icon.svg</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="scrollArea">
@@ -38,7 +34,7 @@
<x>0</x>
<y>0</y>
<width>453</width>
<height>570</height>
<height>547</height>
</rect>
</property>
<widget class="QGroupBox" name="groupBox">
@@ -70,7 +66,7 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::NoButton</set>
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
+4 -1
View File
@@ -20,7 +20,10 @@ from .tools.resources import (
)
pyperclip()
from .flux_editor import Flux_Editor
try:
from .flux_editor import Flux_Editor
except NameError:
print('404')
class PgFlux:
+511 -283
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -5,9 +5,10 @@
[general]
name=CenRa_FLUX
qgisMinimumVersion=3.0
qgisMaximumVersion=4.99
supportsQt6=True
description=Permet d'ouvrire une table dans la base PostGis
version=3.15
version=3.23
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
@@ -32,7 +33,7 @@ icon=icon.png
# experimental flag
experimental=False
changelog=<h2>CenRa_FLUX:</h2></br><p><h3>15/12/2025 - Version 3.15: </h3> - information visuel des droit d access a la donnee sur tout les base.</p></br><p><h3>08/12/2025 - Version 3.14: </h3> - message d erreur pour les drois de couche sur la DB.</p></br><p><h3>08/12/2025 - Version 3.13: </h3> - Detection des droit utilisateur.</p></br><p><h3>25/09/2025 - Version 3.12: </h3> - version +1.</p></br><p><h3>25/09/2025 - Version 3.11: </h3> - Correctife sur les code 00.</p></br><p><h3>24/09/2025 - Version 3.10: </h3> - Erreur sur l ouverture des couche raster. </p></br><p><h3>24/09/2025 - Version 3.9: </h3> - bugfix lier aux extention pgsql.</p></br><p><h3>09/09/2025 - Version 3.8: </h3> - Bug REF fix.</p></br><p><h3>05/09/2025 - Version 3.7: </h3> - Ouverture de projet QGIS contenue dans la base de donnees.</p></br><p><h3>30/07/2025 - Version 3.6: </h3> - Correctife de bug.</p></br><p><h3>29/07/2025 - Version 3.5: </h3> - Bug fix sur les donnee raster.</p></br><p><h3>23/07/2025 - Version 3.4: </h3> - Ouverture raster dans la base SIG.</p></br><p><h3>23/07/2025 - Version 3.3: </h3> - Optimisation des chargement.</p></br><p><h3>22/07/2025 - Version 3.2: </h3> - Visualisation des format raster et vecteur dans REF.</p></br><p><h3>21/07/2025 - Version 3.1: </h3> - Bug fix pour l'ouverture de plus de 5 couches.</p></br><p><h3>19/05/2025 - Version 3.0: </h3> - Compatible PyQt5 et PyQt6.</p></br><p><h3>09/04/2025 - Version 2.9: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 2.8: </h3> - Optimisation pour le TT.</p></br><p><h3>07/04/2025 - Version 2.7: </h3> - mode debug.</p></br><p><h3>03/04/2025 - Version 2.6: </h3> - Mise a jour de securite.</p></br><p><h3>20/03/2025 - Version 2.5: </h3> - Visualisation distincte des couches ne se trouvant pas dans l'antenne.</p></br><p><h3>13/02/2025 - Version 2.4: </h3> - Ajoute redimensionnement et déplacement mollette.</p></br><p><h3>05/02/2025 - Version 2.3: </h3> - Bouton de visualisation des couches se trouvent uniquement dans le canva de la carte.</p></br><p><h3>07/01/2025 - Version 2.2: </h3> - ByPass du certif ssl ci erreur.</p></br><p><h3>22/10/2024 - Version 2.1:</h3> - Correctif de bug.</br> - Evolution de la limit de 3 à 5. </br></p></br><p><h3>22/10/2024 - Version 2.0:</h3> - Reformatage du code.</br></p></br><p><h3>03/10/2024 - Version 1.14:</h3> - Remonte la fênetre dans la pille.</br></p><p><h3>13/09/2024 - Version 1.13:</h3>- MAJ sur le lien du changelog</br>- Bug-fix: Ouvre MultiPolygone et Polygon séparément.</p></br><p><h3>10/09/2024 - Version 1.11:</h3>- Ouverture de table contenant plusieurs géométries.</p></br><p><h3>26/08/2024 - Version 1.10:</h3>- Ajoute d'un changelog et vérification de mise à jour.</p>
changelog=<h2>CenRa_FLUX:</h2></br><p><h3>21/05/2026 - Version 3.23: </h3> - Optimisation des performances hors connexion.</p></br><p><h3>23/03/2026 - Version 3.22: </h3> - Pache mineur.</p></br><p><h3>12/03/2026 - Version 3.21: </h3> - qgisMaximumVersion est 4.0.</p></br><p><h3>05/03/2026 - Version 3.20: </h3> - Visualisation des metadonnees avec un tooltip au survol de la couche.</p></br><p><h3>26/02/2026 - Version 3.19: </h3> - Visualisation des droits pour les vues materialisees.</p></br><p><h3>25/02/2026 - Version 3.18: </h3> - Filtre par secteur geographique compatible avec les favoris.</p></br><p><h3>12/02/2026 - Version 3.17: </h3> - Favorit dans la BD Ref.</p></br><p><h3>11/02/2026 - Version 3.16: </h3> - Creation de favori et visualisation.</p></br><p><h3>10/02/2026 - Version 3.15: </h3> - Sauvegarde la recherche.</p></br><p><h3>08/12/2025 - Version 3.14: </h3> - message d'erreur pour les drois de couche sur la DB.</p></br><p><h3>08/12/2025 - Version 3.13: </h3> - Detection des droit utilisateur.</p></br><p><h3>25/09/2025 - Version 3.12: </h3> - version +1.</p></br><p><h3>25/09/2025 - Version 3.11: </h3> - Correctife sur les code 00.</p></br><p><h3>24/09/2025 - Version 3.10: </h3> - Erreur sur l ouverture des couche raster. </p></br><p><h3>24/09/2025 - Version 3.9: </h3> - bugfix lier aux extention pgsql.</p></br><p><h3>09/09/2025 - Version 3.8: </h3> - Bug REF fix.</p></br><p><h3>05/09/2025 - Version 3.7: </h3> - Ouverture de projet QGIS contenue dans la base de donnees.</p></br><p><h3>30/07/2025 - Version 3.6: </h3> - Correctife de bug.</p></br><p><h3>29/07/2025 - Version 3.5: </h3> - Bug fix sur les donnee raster.</p></br><p><h3>23/07/2025 - Version 3.4: </h3> - Ouverture raster dans la base SIG.</p></br><p><h3>23/07/2025 - Version 3.3: </h3> - Optimisation des chargement.</p></br><p><h3>22/07/2025 - Version 3.2: </h3> - Visualisation des format raster et vecteur dans REF.</p></br><p><h3>21/07/2025 - Version 3.1: </h3> - Bug fix pour l'ouverture de plus de 5 couches.</p></br><p><h3>19/05/2025 - Version 3.0: </h3> - Compatible PyQt5 et PyQt6.</p></br><p><h3>09/04/2025 - Version 2.9: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 2.8: </h3> - Optimisation pour le TT.</p></br><p><h3>07/04/2025 - Version 2.7: </h3> - mode debug.</p></br><p><h3>03/04/2025 - Version 2.6: </h3> - Mise a jour de securite.</p></br><p><h3>20/03/2025 - Version 2.5: </h3> - Visualisation distincte des couches ne se trouvant pas dans l'antenne.</p></br><p><h3>13/02/2025 - Version 2.4: </h3> - Ajoute redimensionnement et déplacement mollette.</p></br><p><h3>05/02/2025 - Version 2.3: </h3> - Bouton de visualisation des couches se trouvent uniquement dans le canva de la carte.</p></br><p><h3>07/01/2025 - Version 2.2: </h3> - ByPass du certif ssl ci erreur.</p></br><p><h3>22/10/2024 - Version 2.1:</h3> - Correctif de bug.</br> - Evolution de la limit de 3 à 5. </br></p></br><p><h3>22/10/2024 - Version 2.0:</h3> - Reformatage du code.</br></p></br><p><h3>03/10/2024 - Version 1.14:</h3> - Remonte la fênetre dans la pille.</br></p><p><h3>13/09/2024 - Version 1.13:</h3>- MAJ sur le lien du changelog</br>- Bug-fix: Ouvre MultiPolygone et Polygon séparément.</p></br><p><h3>10/09/2024 - Version 1.11:</h3>- Ouverture de table contenant plusieurs géométries.</p></br><p><h3>26/08/2024 - Version 1.10:</h3>- Ajoute d'un changelog et vérification de mise à jour.</p>
# deprecated flag (applies to the whole plugin, not just a single version)
deprecated=False
+51 -7
View File
@@ -2,13 +2,57 @@
schemaname_distinct = """SELECT DISTINCT schemaname from pg_catalog.pg_tables
WHERE schemaname NOT LIKE '_archives' AND schemaname NOT LIKE 'topology' AND schemaname NOT LIKE 'information_schema' AND schemaname NOT LIKE 'pg_catalog' and schemaname NOT LIKE 'public' AND schemaname NOT LIKE '_trier'
order by schemaname;"""
schemaname_list_ref = """SELECT schemaname,tablename from pg_catalog.pg_tables
WHERE schemaname NOT LIKE '_archives' AND schemaname NOT LIKE 'topology' AND schemaname NOT LIKE 'information_schema' AND schemaname NOT LIKE 'pg_catalog' and schemaname NOT LIKE 'public' AND schemaname NOT LIKE '_trier'
order by schemaname,tablename;"""
schemaname_list = """(SELECT schemaname,tablename from pg_catalog.pg_tables
where schemaname like 'trav%' or schemaname like '\\_ag%' or schemaname like '\\_00%' or schemaname like '\\_01%' or schemaname like '\\_07%' or schemaname like '\\_26%' or schemaname like '\\_form%' or schemaname like '\\_42%' or schemaname like '\\_69%' order by schemaname,tablename)
UNION
(SELECT schemaname,matviewname AS tablename FROM pg_catalog.pg_matviews order by schemaname,tablename) order by schemaname,tablename;"""
schemaname_list_ref = """
WITH TableList AS (SELECT
schemaname,
tablename
FROM pg_catalog.pg_tables
WHERE
schemaname NOT LIKE '_archives' AND schemaname NOT LIKE 'topology' AND schemaname NOT LIKE 'information_schema' AND schemaname NOT LIKE 'pg_catalog' and schemaname NOT LIKE 'public' AND schemaname NOT LIKE '_trier'
ORDER BY schemaname,tablename),
TableDescription AS (SELECT
schemaname,
tablename,
description
FROM TableList
LEFT JOIN pg_description ON objoid = (quote_ident(schemaname)||'.'||quote_ident(tablename))::regclass
ORDER BY schemaname, tablename)
SELECT * FROM TableDescription;
"""
schemaname_list = """
WITH
TableList as (SELECT
schemaname,
tablename
FROM pg_catalog.pg_tables
WHERE schemaname LIKE 'trav%' OR schemaname LIKE '_ag%' OR schemaname LIKE '_00%' OR schemaname LIKE '_01%' OR schemaname LIKE '_07%' OR schemaname LIKE '_26%' OR schemaname LIKE '_form%' OR schemaname LIKE '_42%' OR schemaname LIKE '_69%'
ORDER BY schemaname,tablename),
ViewList as (SELECT
schemaname,
matviewname AS tablename
FROM pg_catalog.pg_matviews
ORDER BY schemaname,tablename),
TableAndView as (SELECT
schemaname,
tablename
FROM TableList
UNION SELECT schemaname,tablename FROM ViewList),
TableViewDescription as (SELECT
schemaname,
tablename,
description
FROM TableAndView
LEFT JOIN pg_description ON objoid = (quote_ident(schemaname)||'.'||quote_ident(tablename))::regclass
ORDER BY schemaname,tablename)
SELECT * FROM TableViewDescription;
"""
geom = "geom"
champ_travaux_prevus_multipolygon = """(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, surface_m2 double precision, surface_ha double precision, date_creation date, date_maj date, geom geometry(MultiPolygon,2154))"""
champ_travaux_prevus_multilinestring = """(gid serial NOT NULL, groupe_gestion text, gestion_lib text, id_gestion text, datedebut date, datefin date, commentaire text, longueur_m double precision, longueur_km double precision, date_creation date, date_maj date, geom geometry(MultiLineString,2154))"""
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

+1 -1
View File
@@ -155,7 +155,7 @@ def maj_verif(NAME):
try:
urllib.request.urlopen('https://google.com')
binar = True
except NameError:
except urllib.error.URLError:
binar = False
if binar:
try:
@@ -1,252 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>910</width>
<height>800</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>910</width>
<height>800</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>910</width>
<height>800</height>
</size>
</property>
<property name="windowTitle">
<string>SIG CEN-RA</string>
</property>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>260</x>
<y>130</y>
<width>171</width>
<height>22</height>
</rect>
</property>
<property name="editable">
<bool>false</bool>
</property>
<property name="currentText">
<string notr="true"/>
</property>
</widget>
<widget class="QComboBox" name="comboBox_2">
<property name="geometry">
<rect>
<x>370</x>
<y>80</y>
<width>171</width>
<height>22</height>
</rect>
</property>
<property name="editable">
<bool>false</bool>
</property>
<property name="currentText">
<string notr="true"/>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>345</x>
<y>10</y>
<width>221</width>
<height>71</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>:/plugins/CenRa_FLUX/logo.jpg</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>370</x>
<y>750</y>
<width>171</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Charger les couches</string>
</property>
</widget>
<widget class="QTableWidget" name="tableWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>170</y>
<width>850</width>
<height>281</height>
</rect>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
<widget class="QTableWidget" name="tableWidget_2">
<property name="geometry">
<rect>
<x>30</x>
<y>550</y>
<width>850</width>
<height>181</height>
</rect>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
</widget>
<widget class="QCommandLinkButton" name="commandLinkButton">
<property name="geometry">
<rect>
<x>400</x>
<y>470</y>
<width>61</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/plugins/CenRa_FLUX/arrow-bottom.png</normaloff>:/plugins/CenRa_FLUX/arrow-bottom.png</iconset>
</property>
<property name="iconSize">
<size>
<width>50</width>
<height>40</height>
</size>
</property>
</widget>
<widget class="QCommandLinkButton" name="commandLinkButton_2">
<property name="geometry">
<rect>
<x>460</x>
<y>470</y>
<width>61</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/plugins/CenRa_FLUX/arrow-up.png</normaloff>:/plugins/CenRa_FLUX/arrow-up.png</iconset>
</property>
<property name="iconSize">
<size>
<width>50</width>
<height>40</height>
</size>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>480</x>
<y>130</y>
<width>171</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Recherche par mots-clés</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>40</x>
<y>150</y>
<width>161</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<family>Calibri</family>
<pointsize>10</pointsize>
<italic>false</italic>
</font>
</property>
<property name="text">
<string>Liste des flux disponibles :</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>30</x>
<y>530</y>
<width>171</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<family>Calibri</family>
<pointsize>10</pointsize>
<italic>false</italic>
</font>
</property>
<property name="text">
<string>Flux sélectionné(s) à charger :</string>
</property>
</widget>
<zorder>label_3</zorder>
<zorder>comboBox</zorder>
<zorder>comboBox_2</zorder>
<zorder>pushButton_2</zorder>
<zorder>tableWidget</zorder>
<zorder>tableWidget_2</zorder>
<zorder>commandLinkButton</zorder>
<zorder>commandLinkButton_2</zorder>
<zorder>lineEdit</zorder>
<zorder>label</zorder>
<zorder>label_2</zorder>
</widget>
<resources/>
<connections/>
</ui>
+29
View File
@@ -386,6 +386,35 @@
<string notr="true">background-color: rgba(255, 255, 255,0.50);</string>
</property>
</widget>
<widget class="QToolButton" name="toolButton_2">
<property name="geometry">
<rect>
<x>700</x>
<y>130</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
<zorder>commandLinkButton_2</zorder>
<zorder>pushButton_2</zorder>
<zorder>label</zorder>
<zorder>tableWidget_2</zorder>
<zorder>comboBox</zorder>
<zorder>lineEdit</zorder>
<zorder>toolButton</zorder>
<zorder>tableWidget</zorder>
<zorder>label_2</zorder>
<zorder>label_3</zorder>
<zorder>comboBox_2</zorder>
<zorder>commandLinkButton</zorder>
<zorder>checkBox</zorder>
<zorder>DeBUG</zorder>
<zorder>toolButton_2</zorder>
<zorder>viewer</zorder>
</widget>
</widget>
</item>
+3 -7
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CenRa_Metabase_editorwidget_base</class>
<widget class="QDialog" name="CenRa_Metabase_editorwidget_base">
<widget class="QDialog" name="CenRa_about_base">
<property name="geometry">
<rect>
<x>0</x>
@@ -13,10 +13,6 @@
<property name="windowTitle">
<string>Journal des modifications</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>../../CenRa_Metabase/tools/ui/icon.svg</normaloff>../../CenRa_Metabase/tools/ui/icon.svg</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="scrollArea">
@@ -38,7 +34,7 @@
<x>0</x>
<y>0</y>
<width>453</width>
<height>570</height>
<height>547</height>
</rect>
</property>
<widget class="QGroupBox" name="groupBox">
@@ -70,7 +66,7 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::NoButton</set>
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

+221
View File
@@ -0,0 +1,221 @@
__copyright__ = "Copyright 2021, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
from qgis.core import QgsApplication
from qgis.PyQt.QtCore import Qt, QUrl, QSettings
from qgis.PyQt.QtGui import QDesktopServices, QIcon
from qgis.PyQt.QtWidgets import QAction
from qgis.utils import iface
import qgis
# include <QSettings>
'''
from pg_metadata.connection_manager import (
store_connections,
validate_connections_names,
)
from pg_metadata.locator import LocatorFilter
from pg_metadata.processing.provider import PgMetadataProvider
from pg_metadata.qgis_plugin_tools.tools.custom_logging import setup_logger
'''
import os
from .about_form import MetabaseAboutDialog
from .tools.resources import (
# plugin_path,
pyperclip,
resources_path,
maj_verif,
)
pyperclip()
try:
from .dock import CenRa_Metabase
from .editor import Metabase_Editor
except NameError:
print('404')
# from CenRa_Metabase.issues import CenRa_Issues
class PgMetadata:
def __init__(self):
""" Constructor. """
self.dock = None
self.editor = None
# self.issues = None
self.provider = None
self.locator_filter = None
self.dock_action = None
self.help_action = None
plugin_dir = os.path.dirname(__file__)
end_find = plugin_dir.rfind('\\') + 1
global NAME
NAME = plugin_dir[end_find:]
maj_verif(NAME)
# Display About window on first use
version = qgis.utils.pluginMetadata('CenRa_METABASE', 'version')
s = QSettings()
versionUse = s.value("metadata/version", 1, type=str)
if str(versionUse) != str(version):
s.setValue("metadata/version", str(version))
print(versionUse, version)
self.open_about_dialog()
# setup_logger('pg_metadata')
# locale, file_path = setup_translation(
# folder=plugin_path("i18n"), file_pattern="CenRa_Metabase_{}.qm")
# if file_path:
# self.translator = QTranslator()
# self.translator.load(file_path)
# noinspection PyCallByClass,PyArgumentList
# QCoreApplication.installTranslator(self.translator)
# noinspection PyPep8Naming
# def initProcessing(self):
# """ Add the QGIS Processing provider. """
# if not self.provider:
# self.provider = PgMetadataProvider()
# QgsApplication.processingRegistry().addProvider(self.provider)
# noinspection PyPep8Naming
def initGui(self):
""" Build the plugin GUI. """
# self.initProcessing()
# self.check_invalid_connection_names()
self.toolBar = iface.addToolBar("CenRa_Metabase")
self.toolBar.setObjectName("CenRa_Metabase")
icon = QIcon(resources_path('icons', 'icon.png'))
icon2 = QIcon(resources_path('icons', 'icon_2.png'))
# Open the online help
self.help_action = QAction(icon, 'CenRa_Metabase', iface.mainWindow())
iface.pluginHelpMenu().addAction(self.help_action)
self.help_action.triggered.connect(self.open_help)
if not self.editor:
self.editor = Metabase_Editor()
self.editor_action = QAction(icon2, 'CenRa_Metabase', None)
self.toolBar.addAction(self.editor_action)
self.editor_action.triggered.connect(self.open_editor)
if not self.dock:
self.dock = CenRa_Metabase()
iface.addDockWidget(Qt.DockWidgetArea(0x2), self.dock)
# Open/close the dock from plugin menu
self.dock_action = QAction(icon, 'CenRa_Metabase', iface.mainWindow())
iface.pluginMenu().addAction(self.dock_action)
self.dock_action.triggered.connect(self.open_dock)
# if not self.issues:
# self.issues = CenRa_Issues()
# self.issues_action = QAction(icon, 'CenRa_Metabase',None)
# self.toolBar.addAction(self.issues_action)
# self.issues_action.triggered.connect(self.open_issues)
'''
if not self.locator_filter:
self.locator_filter = LocatorFilter(iface)
iface.registerLocatorFilter(self.locator_filter)
@staticmethod
def check_invalid_connection_names():
""" Check for invalid connection names in the QgsSettings. """
valid, invalid = validate_connections_names()
n_invalid = len(invalid)
if n_invalid == 0:
return
invalid_text = ', '.join(invalid)
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setWindowTitle(tr('PgMetadata: Database connection(s) not available'))
msg.setText(tr(
f'{n_invalid} connection(s) listed in PgMetadata’s settings are invalid or '
f'no longer available: {invalid_text}'))
msg.setInformativeText(tr(
'Do you want to remove these connection(s) from the PgMetadata settings? '
'(You can also do this later with the “Set Connections” tool.)'))
msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
clicked = msg.exec()
if clicked == QMessageBox.Yes:
iface.messageBar().pushSuccess('PgMetadata', tr(f'{n_invalid} invalid connection(s) removed.'))
store_connections(valid)
if clicked == QMessageBox.No:
iface.messageBar().pushInfo('PgMetadata', tr(f'Keeping {n_invalid} invalid connections.'))
'''
def open_about_dialog(self):
"""
About dialog
"""
dialog = MetabaseAboutDialog(iface)
dialog.exec()
def open_help():
""" Open the online help. """
QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
def open_dock(self):
""" Open the dock. """
self.dock.show()
self.dock.raise_()
def open_editor(self):
self.editor.show()
self.editor.raise_()
# def open_issues(self):
# self.issues.show()
# self.issues.raise_()
def unload(self):
""" Unload the plugin. """
# if self.editor:
# iface.removePluginMenu('CenRa_Metabase',self.editor_action)
# self.editor.removeToolBarIcon(self.editor_action)
if self.dock:
iface.removeDockWidget(self.dock)
self.dock.deleteLater()
if self.provider:
QgsApplication.processingRegistry().removeProvider(self.provider)
del self.provider
if self.locator_filter:
iface.deregisterLocatorFilter(self.locator_filter)
del self.locator_filter
if self.help_action:
iface.pluginHelpMenu().removeAction(self.help_action)
del self.help_action
if self.dock_action:
iface.pluginMenu().removeAction(self.dock_action)
del self.dock_action
@staticmethod
def run_tests(pattern='test_*.py', package=None):
"""Run the test inside QGIS."""
try:
from pathlib import Path
from pg_metadata.qgis_plugin_tools.infrastructure.test_runner import (
test_package,
)
if package is None:
package = '{}.__init__'.format(Path(__file__).parent.name)
test_package(package, pattern)
except (AttributeError, ModuleNotFoundError):
message = 'Could not load tests. Are you using a production package?'
print(message) # NOQA
+1
View File
@@ -0,0 +1 @@
# CenRa_Metabase
+10
View File
@@ -0,0 +1,10 @@
__copyright__ = "Copyright 2021, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
# noinspection PyPep8Naming
def classFactory(iface): # pylint: disable=invalid-name
_ = iface
from CenRa_METABASE.CenRa_Metabase import PgMetadata
return PgMetadata()
+46
View File
@@ -0,0 +1,46 @@
import os.path
from pathlib import Path
from qgis.PyQt import uic
# from qgis.PyQt.QtGui import QPixmap
from qgis.PyQt.QtWidgets import QDialog
from .tools.resources import devlog
ABOUT_FORM_CLASS, _ = uic.loadUiType(
os.path.join(
str(Path(__file__).resolve().parent),
'tools/ui',
'CenRa_about_form.ui'
)
)
class MetabaseAboutDialog(QDialog, ABOUT_FORM_CLASS):
""" About - Let the user display the about dialog. """
def __init__(self, iface, parent=None):
super().__init__(parent)
self.iface = iface
self.setupUi(self)
self.viewer.setHtml(devlog('CenRa_METABASE'))
self.rejected.connect(self.onReject)
self.buttonBox.rejected.connect(self.onReject)
self.buttonBox.accepted.connect(self.onAccept)
def onAccept(self):
"""
Save options when pressing OK button
"""
self.accept()
def onReject(self):
"""
Run some actions when
the user closes the dialog
"""
self.close()
+453
View File
@@ -0,0 +1,453 @@
"""Dock file."""
__copyright__ = 'Copyright 2020, 3Liz'
__license__ = 'GPL version 3'
__email__ = 'info@3liz.org'
import logging
import os
from collections import namedtuple
from enum import Enum
from functools import partial
from pathlib import Path
from xml.dom.minidom import parseString
from qgis.core import (
QgsApplication,
QgsProviderRegistry,
QgsSettings,
)
from qgis.PyQt.QtCore import QLocale, QUrl
from qgis.PyQt.QtGui import QDesktopServices, QIcon
from qgis.PyQt.QtPrintSupport import QPrinter
# from qgis.PyQt.QtWebKitWidgets import QWebPage
from qgis.PyQt.QtWidgets import (
QAction,
QDockWidget,
QFileDialog,
QMenu,
QToolButton,
)
from qgis.utils import iface
import qgis
from .tools.resources import (
load_ui,
resources_path,
)
try:
from .tools.PythonSQL import login_base
except ValueError:
print('Pas de fichier PythonSQL')
DOCK_CLASS = load_ui('CenRa_Metabase_dockwidget_base.ui')
LOGGER = logging.getLogger('CenRa_Metabase')
class Format(namedtuple('Format', ['label', 'ext'])):
""" Format available for exporting metadata. """
pass
class OutputFormats(Format, Enum):
""" Output format for a metadata sheet. """
PDF = Format(label='PDF', ext='pdf')
HTML = Format(label='HTML', ext='html')
DCAT = Format(label='DCAT', ext='xml')
class CenRa_Metabase(QDockWidget, DOCK_CLASS):
def __init__(self, parent=None):
_ = parent
super().__init__()
self.setupUi(self)
self.settings = QgsSettings()
self.current_datasource_uri = None
self.current_connection = None
# self.viewer.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
# self.viewer.page().linkClicked.connect(self.open_link)
# Help button
self.external_help.setText('')
self.external_help.setIcon(QIcon(QgsApplication.iconPath('mActionHelpContents.svg')))
self.external_help.clicked.connect(self.open_external_help)
# Flat table button
self.flatten_dataset_table.setText('')
# self.flatten_dataset_table.setToolTip(tr("Add the catalog table"))
self.flatten_dataset_table.setIcon(QgsApplication.getThemeIcon("/mActionAddHtml.svg"))
# self.flatten_dataset_table.clicked.connect(self.add_flatten_dataset_table)
# Settings menu
self.config.setAutoRaise(True)
# self.config.setToolTip(tr("Settings"))
self.config.setPopupMode(QToolButton.ToolButtonPopupMode(2))
self.config.setIcon(QgsApplication.getThemeIcon("/mActionOptions.svg"))
self.auto_open_dock_action = QAction(
("Dommage, cette option n'existe pas encore."),
iface.mainWindow())
self.auto_open_dock_action.setCheckable(True)
self.auto_open_dock_action.setChecked(
self.settings.value("pgmetadata/auto_open_dock", True, type=bool)
)
self.auto_open_dock_action.triggered.connect(self.save_auto_open_dock)
menu = QMenu()
menu.addAction(self.auto_open_dock_action)
self.config.setMenu(menu)
# Setting PDF/HTML menu
self.save_button.setAutoRaise(True)
# self.save_button.setToolTip(tr("Save metadata"))
self.save_button.setPopupMode(QToolButton.ToolButtonPopupMode(2))
self.save_button.setIcon(QIcon(QgsApplication.iconPath('mActionFileSave.svg')))
self.save_as_pdf = QAction(
('Enregistrer en PDF') + '…',
iface.mainWindow())
self.save_as_pdf.triggered.connect(partial(self.export_dock_content, OutputFormats.PDF))
self.save_as_html = QAction(
('Enregistrer en HTML') + '…',
iface.mainWindow())
self.save_as_html.triggered.connect(partial(self.export_dock_content, OutputFormats.HTML))
self.save_as_dcat = QAction(
('Enregistrer en DCAT') + '…',
iface.mainWindow())
self.save_as_dcat.triggered.connect(partial(self.export_dock_content, OutputFormats.DCAT))
self.menu_save = QMenu()
self.menu_save.addAction(self.save_as_pdf)
self.menu_save.addAction(self.save_as_html)
self.menu_save.addAction(self.save_as_dcat)
self.save_button.setMenu(self.menu_save)
self.save_button.setEnabled(False)
self.metadata = QgsProviderRegistry.instance().providerMetadata('postgres')
# Display message in the dock
# if not settings_connections_names():
# self.default_html_content_not_installed()
# else:
self.default_html_content_not_pg_layer()
iface.layerTreeView().currentLayerChanged.connect(self.layer_changed)
try:
login_base()
iface.layerTreeView().currentLayerChanged.connect(self.layer_changed)
except ValueError:
# qgis.utils.plugins['CenRa_METABASE'].initGui()
qgis.utils.plugins['CenRa_METABASE'].unload()
# self.default_html_content_not_pg_layer()
if iface.activeLayer():
layer = iface.activeLayer()
iface.layerTreeView().setCurrentLayer(None)
iface.layerTreeView().setCurrentLayer(layer)
def export_dock_content(self, output_format: OutputFormats):
""" Export the current displayed metadata sheet to the given format. """
layer_name = iface.activeLayer().name()
file_path = os.path.join(
os.environ['USERPROFILE'],
'Desktop\\{name}.{ext}'.format(name=layer_name, ext=output_format.ext)
)
output_file = QFileDialog.getSaveFileName(
self,
("Enregistrer en {format}").format(format=output_format.label),
file_path,
"{label} (*.{ext})".format(
label=output_format.label,
ext=output_format.ext,
)
)
if output_file[0] == '':
return
self.settings.setValue("UI/lastFileNameWidgetDir", os.path.dirname(output_file[0]))
output_file_path = output_file[0]
parent_folder = str(Path(output_file_path).parent)
if output_format == OutputFormats.PDF:
printer = QPrinter()
printer.setOutputFormat(QPrinter.OutputFormat(1))
# printer.setPageMargins(20,20,20,20,QPrinter.Unit(0))
printer.setOutputFileName(output_file_path)
self.viewer.print(printer)
iface.messageBar().pushSuccess(
("Export PDF"),
(
"The metadata has been exported as PDF successfully in "
"<a href=\"{}\">{}</a>").format(parent_folder, output_file_path)
)
elif output_format in [OutputFormats.HTML, OutputFormats.DCAT]:
if output_format == OutputFormats.HTML:
data_str = self.viewer.page().currentFrame().toHtml()
else:
layer = iface.activeLayer()
uri = layer.dataProvider().uri()
dataall = self.sql_info(uri)
data = self.sql_to_xml(dataall)
with open(resources_path('xml', 'dcat.xml'), encoding='utf8') as xml_file:
xml_template = xml_file.read()
xml = parseString(xml_template.format(language=data[0][0], content=data[0][1]))
data_str = xml.toprettyxml()
with open(output_file[0], "w", encoding='utf8') as file_writer:
file_writer.write(data_str)
iface.messageBar().pushSuccess(
("Export") + ' ' + output_format.label,
(
"The metadata has been exported as {format} successfully in "
"<a href=\"{folder}\">{path}</a>").format(
format=output_format.label, folder=parent_folder, path=output_file_path)
)
def save_auto_open_dock(self):
""" Save settings about the dock. """
self.settings.setValue("pgmetadata/auto_open_dock", self.auto_open_dock_action.isChecked())
def sql_to_xml(self, dataall):
distribution = ''
for y in dataall[1]:
distribution = distribution + ('<dcat:distribution>' + '<dcat:Distribution>' + '<dct:title>{data}</dct:title>'.format(data=y[0]) + '<dcat:downloadURL>{data}</dcat:downloadURL>'.format(data=y[1]) + '<dcat:mediaType>{data}</dcat:mediaType>'.format(data=y[2]) + '<dct:format>{data}</dct:format>'.format(data=y[3]) + '<dct:bytesize>{data}</dct:bytesize>'.format(data=y[4]) + '</dcat:Distribution>' + '</dcat:distribution>')
publisher = ''
for z in dataall[2]:
publisher = publisher + ('<dct:publisher>' + '<foaf:Organization>' + '<foaf:name>{data}</foaf:name>'.format(data=z[1]) + '<foaf:mbox>{data}</foaf:mbox>'.format(data=z[3]) + '</foaf:Organization>' + '</dct:publisher>')
data_str = [[dataall[0][26], '<dct:identifier>{data}</dct:identifier>'.format(data=dataall[0][1]) + '<dct:title>{data}</dct:title>'.format(data=dataall[0][4]) + '<dct:description>{data}</dct:description>'.format(data=dataall[0][5]) + '<dct:language>{data}</dct:language>'.format(data=dataall[0][26]) + '<dct:spatial>{data}</dct:spatial>'.format(data=dataall[0][28]) + '<dct:created rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">{data}</dct:created>'.format(data=dataall[0][20]) + '<dct:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">{data}</dct:issued>'.format(data=dataall[0][11]) + '<dct:modified rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">{data}</dct:modified>'.format(data=dataall[0][21]) + '<dct:license>{data}</dct:license>'.format(data=dataall[0][13]) + distribution + publisher + '<dcat:theme>{data}</dcat:theme>'.format(data=", ".join(str(x) for x in dataall[0][24])) + '<dcat:keyword>{data}</dcat:keyword>'.format(data=", ".join(str(x) for x in dataall[0][6])) + '<dct:accrualPeriodicity>{data}</dct:accrualPeriodicity>'.format(data=dataall[0][12])]]
return data_str
@staticmethod
def sql_for_layer(uri, output_format: OutputFormats):
""" Get the SQL query for a given layer and output format. """
locale = QgsSettings().value("locale/userLocale", QLocale().name())
locale = locale.split('_')[0].lower()
if output_format == [OutputFormats.HTML, OutputFormats.DCAT]:
sql = (
"SELECT pgmetadata.get_dataset_item_html_content('{schema}', '{table}', '{locale}');"
).format(schema=uri.schema(), table=uri.table(), locale=locale)
else:
raise NotImplementedError('Output format is not yet implemented.')
return sql
def layer_changed(self, layer):
""" When the layer has changed in the legend, we must check this new layer. """
self.current_datasource_uri = None
self.current_connection = None
self.ce_trouve_dans_psql(layer)
def add_flatten_dataset_table(self):
""" Add a flatten dataset table with all links and contacts. """
'''
connections, message = connections_list()
if not connections:
LOGGER.critical(message)
self.set_html_content('PgMetadata', message)
return
if len(connections) > 1:
dialog = QInputDialog()
dialog.setComboBoxItems(connections)
dialog.setWindowTitle(tr("Database"))
dialog.setLabelText(tr("Choose the database to add the catalog"))
if not dialog.exec_():
return
connection_name = dialog.textValue()
else:
connection_name = connections[0]
metadata = QgsProviderRegistry.instance().providerMetadata('postgres')
connection = metadata.findConnection(connection_name)
locale = QgsSettings().value("locale/userLocale", QLocale().name())
locale = locale.split('_')[0].lower()
uri = QgsDataSourceUri(connection.uri())
uri.setTable(f'(SELECT * FROM pgmetadata.export_datasets_as_flat_table(\'{locale}\'))')
uri.setKeyColumn('uid')
layer = QgsVectorLayer(uri.uri(), '{} - {}'.format(tr("Catalog"), connection_name), 'postgres')
QgsProject.instance().addMapLayer(layer)
'''
@staticmethod
def open_external_help():
QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
@staticmethod
def open_link(url):
QDesktopServices.openUrl(url)
def set_html_content(self, title=None, body=None):
""" Set the content in the dock. """
# ink_logo=resources_path('icons', 'CEN_RA.png')
css_file = resources_path('css', 'dock.css')
with open(css_file, 'r', encoding='utf8') as f:
css = f.read()
html = '<html><head>'
# html += '<script src="http://ignf.github.io/geoportal-sdk/latest/dist/2d/GpSDK2D.js" defer ></script>'
html += '<style>{css}</style></head><body>'.format(css=css)
# html += '<link rel="stylesheet" href="http://ignf.github.io/geoportal-sdk/latest/dist/2d/GpSDK2D.css" >'
# html += '<script src="file:///C:/Users/tlaveille/Desktop/maps.js" defer></script>'
# html += '<noscript>Your browser does not support JavaScript!</noscript>'
if title:
html += '<h2>{title} <img class=logo src=https://i2.wp.com/www.cen-rhonealpes.fr/wp-content/uploads/2013/04/cen-rhonealpes-couleurs1.jpg?w=340&ssl=1></h2>'.format(title=title)
if body:
html += body
html += '</body></html>'
# It must be a file, even if it does not exist on the file system.
# base_url = QUrl.fromLocalFile(resources_path('images', 'must_be_a_file.png'))
self.viewer.setHtml(html)
def ce_trouve_dans_psql(self, layer):
try:
uri = layer.dataProvider().uri()
except AttributeError:
self.default_html_content_not_pg_layer()
self.save_button.setEnabled(False)
uri = ''
if uri != '':
if not uri.table():
layertype = layer.providerType().lower()
if layertype == 'wms' or layertype == 'wfs':
self.set_html_to_wms(layer)
else:
self.default_html_content_not_pg_layer()
self.save_button.setEnabled(False)
else:
data_count = self.sql_check(uri)
# print(data_count)
if data_count == 0:
self.default_html_content_not_metadata()
self.save_button.setEnabled(False)
else:
self.build_html_content(layer, uri)
self.save_button.setEnabled(True)
def build_html_content(self, layer, uri):
body = ''
dataall = self.sql_info(uri)
data = dataall[0]
data_url = dataall[1]
data_contact = dataall[2]
# print(len(data_url))
# data_collonne = [field.name() for field in layer.dataProvider().fields()]
body += '<div><h3>Identification</h3><table class="table table-condensed">'
body += '<tr><th>Titre</th><td>{data[4]}</td></tr>'.format(data=data)
body += '<tr><th>Description</th><td>{data[5]}</td></tr>'.format(data=data)
body += '<tr><th>Categories</th><td>{data}</td></tr>'.format(data=(", ".join(str(x) for x in data[6])))
body += '<tr><th>Thèmes</th><td>{data}</td></tr>'.format(data=(", ".join(str(x) for x in data[24])))
body += '<tr><th>Mots-clés</th><td>{data[7]}</td></tr>'.format(data=data)
body += '<tr><th>Dernier mise à jour</th><td>{data[23]}</td></tr>'.format(data=data)
body += '<tr><th>Langue</th><td>{data[26]}</td></tr>'.format(data=data)
body += '</table></div>'
body += '<div><h3>Properties spatial</h3><table class="table table-condensed">'
body += '<tr><th>Niveau</th><td>{data[8]}</td></tr>'.format(data=data)
body += '<tr><th>Echelle minimum</th><td>{data[9]}</td></tr>'.format(data=data)
body += '<tr><th>Echelle maximum</th><td>{data[10]}</td></tr>'.format(data=data)
body += '<tr><th>Nombre d\'entités </th><td>{data[15]}</td></tr>'.format(data=data)
body += '<tr><th>Type de géométrie</th><td>{data[16]}</td></tr>'.format(data=data)
body += '<tr><th>Nom de projection</th><td>{data[17]}</td></tr>'.format(data=data)
body += '<tr><th>ID de projection</th><td>{data[18]}</td></tr>'.format(data=data)
body += '<tr><th>Emprise</th><td>{data[28]}</td></tr>'.format(data=data)
body += '</table></div>'
# body += '<div id="map"></div>'
body += '<div><h3>Publication</h3><table class="table table-condensed">'
body += '<tr><th>Date</th><td>{data[11]}</td></tr>'.format(data=data)
body += '<tr><th>Fréquence de mise à jour</th><td>{data[12]}</td></tr>'.format(data=data)
body += '<tr><th>Licence</th><td>{data[13]}</td></tr>'.format(data=data)
body += '<tr><th>Licence attribué</th><td>{data[25]}</td></tr>'.format(data=data)
body += '<tr><th>Restriction</th><td>{data[14]}</td></tr>'.format(data=data)
body += '</table></div>'
body += '<div><h3>Lien</h3><table class="table table-condensed table-striped table-bordered">'
body += '<tr><th>Type</th><th>URL</th><th>Type MIME</th><th>Format</th><th>Taille</th></tr>'
for value_url in data_url:
body += '<tr><td>{value_url[0]}</td><td>{value_url[1]}</td><td>{value_url[2]}</td><td>{value_url[3]}</td><td>{value_url[4]}</td></tr>'.format(value_url=value_url)
body += '</table></div>'
'''
body += '<div><h3>Liste des champs</h3><table class="table table-condensed table-striped table-bordered">'
for collonne in data_collonne:
body += '<tr><th>{collonne}</th><td>{defini}</td></tr>'.format(collonne=collonne,defini='')
body += '</table></div>'
'''
body += '<div><h3>Contacts</h3><table class="table table-condensed table-striped table-bordered">'
body += '<tr><th>Rôle</th><th>Nom</th><th>Organisation</th><th>Email</th><th>Télèphone</th></tr>'
for value_contact in data_contact:
body += '<tr><td>{value_contact[0]}</td><td>{value_contact[1]}</td><td>{value_contact[2]}</td><td>{value_contact[3]}</td><td>{value_contact[4]}</td></tr>'.format(value_contact=value_contact)
body += '</table></div>'
body += '<div><h3>Metadata</h3><table class="table table-condensed">'
body += '<tr><th>Table</th><td>{data[2]}</td></tr>'.format(data=data)
body += '<tr><th>Schema</th><td>{data[3]}</td></tr>'.format(data=data)
body += '<tr><th>Date de création</th><td>{data[20]}</td></tr>'.format(data=data)
body += '<tr><th>Date de modification</th><td>{data[21]}</td></tr>'.format(data=data)
body += '<tr><th>Encodage</th><td>{data[27]}</td></tr>'.format(data=data)
body += '<tr><th>UUID</th><td>{data[1]}</td></tr>'.format(data=data)
body += '</table></div>'
self.set_html_content(
layer.name(), body)
def set_html_to_wms(self, layer):
self.set_html_content(
'CenRa Metadata', (layer.htmlMetadata()))
def default_html_content_not_pg_layer(self):
""" When it's not a PostgreSQL layer. """
self.set_html_content(
'CenRa Metadata', ('Vous devez cliquer sur une couche dans la légende qui est stockée dans PostgreSQL.'))
def default_html_content_not_metadata(self):
self.set_html_content(
'CenRa Metadata', ('La couche ne contien pas de métadonnée.'))
def sql_check(self, uri):
cur = login_base()
table = uri.table()
schema = uri.schema()
sql_count = """SELECT count(uid) FROM metadata.dataset
WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
cur.execute(sql_count)
data_count = cur.fetchall()
cur.close()
return data_count[0][0]
def sql_info(self, uri):
cur = login_base()
table = uri.table()
schema = uri.schema()
# [s for s in iface.activeLayer().source().split(" ") if "dbname" in s][0].split("'")[1]
sql_find = """SELECT *,right(left(st_astext(geom,2),-2),-9) FROM metadata.dataset
WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
cur.execute(sql_find)
data_general = cur.fetchall()
sql_findurl = """SELECT type,url,mime,format,taille FROM metadata.dataurl WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
cur.execute(sql_findurl)
data_url = cur.fetchall()
sql_findcontact = """SELECT role,nom,organisation,email,telephone FROM metadata.datacontact WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
cur.execute(sql_findcontact)
data_contact = cur.fetchall()
cur.close()
return data_general[0], data_url, data_contact
+775
View File
@@ -0,0 +1,775 @@
import logging
import os
# from collections import namedtuple
# from enum import Enum
# from functools import partial
# from pathlib import Path
# from xml.dom.minidom import parseString
# from qgis.gui import *
from qgis.core import (
QgsApplication,
QgsSettings,
QgsGeometry,
QgsWkbTypes,
Qgis,
)
from qgis.PyQt import QtGui, QtCore
from qgis.PyQt.QtGui import QIcon
# from qgis.PyQt.QtPrintSupport import QPrinter
# from qgis.PyQt.QtWebKitWidgets import QWebPage
import psycopg2
from qgis.PyQt.QtWidgets import (
QDialog,
QFileDialog,
QTableWidgetItem,
)
from qgis.utils import iface
try:
from .tools.PythonSQL import login_base
except ValueError:
print('Pas de fichier PythonSQL')
from .tools.resources import (
load_ui,
resources_path,
# send_issues,
)
# from .issues import CenRa_Issues
EDITOR_CLASS = load_ui('CenRa_Metabase_editorwidget_base.ui')
LOGGEr = logging.getLogger('CenRa_Metabase')
class Metabase_Editor(QDialog, EDITOR_CLASS):
def __init__(self, parent=None):
_ = parent
super().__init__()
self.setupUi(self)
self.settings = QgsSettings()
self.setWindowIcon(QtGui.QIcon(resources_path('icons', 'icon.png')))
self.import_xml.setAutoRaise(True)
self.import_xml.setText('')
self.import_xml.setIcon(QIcon(QgsApplication.iconPath('mActionAddHtml.svg')))
self.import_xml.clicked.connect(self.py_import_xml)
self.issues_app.setAutoRaise(True)
self.issues_app.setText('')
self.issues_app.setIcon(QIcon(QgsApplication.iconPath('mIconInfo.svg')))
self.auto_adding.setIcon(QtGui.QIcon(resources_path('icons', 'auto_add.png')))
self.auto_adding.hide()
if os.getlogin() == 'tlaveille' or 'lpoulin' or 'rclement':
self.auto_adding.show()
self.auto_adding.clicked.connect(self.auto_run)
# self.issues_app.clicked.connect(self.issues_open)
self.categories_select_view.itemDoubleClicked.connect(self.add_categories_view)
self.categories_view.itemDoubleClicked.connect(self.deleter_categories_view)
self.themes_select_view.itemDoubleClicked.connect(self.add_themes_view)
self.themes_view.itemDoubleClicked.connect(self.deleter_themes_view)
self.annuler_button.clicked.connect(self.close)
self.ok_button.clicked.connect(self.add_metadata)
self.add_lien_button.clicked.connect(self.add_lien)
self.add_contact_button.clicked.connect(self.add_contact)
self.delete_lien_button.clicked.connect(self.delete_lien)
self.delete_contact_button.clicked.connect(self.delete_contact)
def auto_run(self):
self.role_box.setCurrentIndex(1)
self.nom_line.setText('LAVEILLE')
self.organisation_box.setCurrentIndex(1)
self.email_line.setText('tom.laveille@cen-rhonealpes.fr')
self.telephone_line.setText('0451260811')
self.add_contact()
self.type_box.setCurrentIndex(16)
self.url_line.setText('www.cen-rhonealpes.fr')
self.mime_box.setCurrentIndex(16)
self.format_box.setCurrentIndex(0)
self.taille_line.setText('45')
self.add_lien()
def add_metadata(self):
table_name = layer.dataProvider().uri().table()
schema_name = layer.dataProvider().uri().schema()
text_titre = self.titre_line.text()
text_description = self.description_text.toPlainText()
text_mots_cles = self.mots_cles_text.toPlainText()
text_date_maj = str(self.date_maj_date.date().toPyDate())
text_langue = self.langue_box.currentText()
row_count_categories = self.categories_view.rowCount()
row_count_themes = self.themes_view.rowCount()
row = 1
array_categories = '{'
while row_count_categories >= row:
if row_count_categories != row:
array_categories += (self.categories_view.item(row - 1, 0).text()) + ', '
else:
array_categories += (self.categories_view.item(row - 1, 0).text())
row = row + 1
array_categories += '}'
row = 1
array_themes = '{'
while row_count_themes >= row:
if row_count_themes != row:
array_themes += (self.themes_view.item(row - 1, 0).text()) + ', '
else:
array_themes += (self.themes_view.item(row - 1, 0).text())
row = row + 1
array_themes += '}'
text_date_creation = str(self.date_creation_date.date().toPyDate())
text_date_modification = str(self.date_modification_date.date().toPyDate())
text_encode = self.encodage_box.currentText()
text_extend = self.extend_plaintext.toPlainText()
int_nbr_entites = (self.nbr_layers.toPlainText())
text_geomtype = self.typegeom_plaintext.toPlainText()
text_crsname = self.crsname_plaintext.toPlainText()
text_crscode = self.crscode_plaintext.toPlainText()
text_niveau = self.niveau_plain.toPlainText()
text_echelle_min = self.echelle_min_plain.toPlainText()
text_echelle_max = self.echelle_max_plain.toPlainText()
if text_echelle_min == '':
text_echelle_min = 'NULL'
if text_echelle_max == '':
text_echelle_max = 'NULL'
text_date_publication = str(self.date_publication_date.date().toPyDate())
text_frequence = self.frequence_box.currentText()
text_restriction = self.restriction_box.currentText()
text_licence = self.licence_box.currentText()
text_licence_attrib = self.licence_attrib_box.currentText()
'''
row_count_link = self.table_lien.rowCount()
row = 1
array_link = ''
while row_count_link >= row:
if row_count_link != row:
array_link += "('" + table_name + "', '" + schema_name + "', '" + (self.table_lien.item(row - 1,1).text()) + "', '" + (self.table_lien.item(row - 1,2).text()) + "', '" + (self.table_lien.item(row - 1,3).text()) + "', '" + (self.table_lien.item(row - 1,4).text()) + "', '" + (self.table_lien.item(row - 1,5).text()) + "')" + ', '
else:
array_link += "('" + table_name + "', '" + schema_name + "', '" + (self.table_lien.item(row - 1,1).text()) + "', '" + (self.table_lien.item(row - 1,2).text()) + "', '" + (self.table_lien.item(row - 1,3).text()) + "', '" + (self.table_lien.item(row - 1,4).text()) + "', '" + (self.table_lien.item(row - 1,5).text()) + "')"
row = row + 1
row_count_contact = self.table_contact.rowCount()
row = 1
array_contact = ''
while row_count_contact >= row:
if row_count_contact != row:
array_contact += "('" + table_name + "', '" + schema_name + "', '" + (self.table_contact.item(row - 1,1).text()) + "', '" + (self.table_contact.item(row - 1,2).text()) + "', '" + (self.table_contact.item(row - 1,3).text()) + "', '" + (self.table_contact.item(row - 1,4).text()) + "', '" + (self.table_contact.item(row - 1,5).text()) + "')" + ', '
else:
array_contact += "('" + table_name + "', '" + schema_name + "', '" + (self.table_contact.item(row - 1,1).text()) + "', '" + (self.table_contact.item(row - 1,2).text()) + "', '" + (self.table_contact.item(row - 1,3).text()) + "', '" + (self.table_contact.item(row - 1,4).text()) + "', '" + (self.table_contact.item(row - 1,5).text()) + "')"
row = row + 1
'''
exist = self.status_metadata(layer)
cur_con = login_base(take=True)
cur = cur_con[0]
con = cur_con[1]
list_champs_sql = ''
values_sql_add = ''
if exist:
SQL_uid = """SELECT uid from metadata.dataset where table_name like '""" + table_name + """' and schema_name like '""" + schema_name + """';"""
cur.execute(SQL_uid)
text_uid = (cur.fetchall())[0][0]
SQL_delete = """DELETE from metadata.dataset where table_name like '""" + table_name + """' and schema_name like '""" + schema_name + """';"""
cur.execute(SQL_delete)
values_sql_add += "'" + text_uid + "',"
list_champs_sql += 'uid,'
global uid_delete_list_link, uid_delete_list_contact
if len(uid_delete_list_link) >= 35:
SQL_delete_link = """DELETE FROM metadata.dataurl WHERE uid IN (""" + uid_delete_list_link[:- 1] + """);"""
cur.execute(SQL_delete_link)
uid_delete_list_link = ''
if len(uid_delete_list_contact) >= 35:
SQL_delete_contact = """DELETE FROM metadata.datacontact WHERE uid IN (""" + uid_delete_list_contact[:- 1] + """);"""
cur.execute(SQL_delete_contact)
uid_delete_list_contact = ''
list_champs_sql += 'table_name, schema_name, title, abstract, keywords, data_last_update, langue, categories, themes, creation_date, update_date, encode, geom, spatial_extent, feature_count, geometry_type, projection_name, projection_authid, spatial_level, minimum_optimal_scale, maximum_optimal_scale, publication_date, publication_frequency, confidentiality, license, license_attribution'
values_sql_add += "'" + table_name + "', '" + schema_name + "', '" + text_titre + "', '" + text_description + "', '" + text_mots_cles + "', '" + text_date_maj + "', '" + text_langue + "', '" + array_categories + "', '" + array_themes + "', '" + text_date_creation + "', '" + text_date_modification + "', '" + text_encode + "', '" + text_extend + "', '" + text_extend + "', '" + int_nbr_entites + "', '" + text_geomtype + "', '" + text_crsname + "', '" + text_crscode + "', '" + text_niveau + "'," + text_echelle_min + "," + text_echelle_max + ",'" + text_date_publication + "', '" + text_frequence + "', '" + text_restriction + "', '" + text_licence + "', '" + text_licence_attrib + "'"
SQL_add = """INSERT INTO metadata.dataset (""" + list_champs_sql + """) VALUES (""" + values_sql_add + """);"""
cur.execute(SQL_add)
global array_link, array_contact
if len(array_link) >= 25:
array_link = array_link[:- 1]
SQL_add_link = """INSERT INTO metadata.dataurl (table_name, schema_name, type, url, mime, format, taille) VALUES """ + array_link + """;"""
cur.execute(SQL_add_link)
array_link = ''
if len(array_contact) >= 25:
array_contact = array_contact[0:- 1]
SQL_add_contact = """INSERT INTO metadata.datacontact (table_name, schema_name, role, nom, organisation, email, telephone) VALUES """ + array_contact + """;"""
cur.execute(SQL_add_contact)
array_contact = ''
con.commit()
cur.close()
self.close()
iface.layerTreeView().setCurrentLayer(None)
iface.layerTreeView().setCurrentLayer(layer)
def raise_(self):
self.activateWindow()
global layer
layer = iface.activeLayer()
global uid_delete_list_link, uid_delete_list_contact, array_link, array_contact
uid_delete_list_link = ''
uid_delete_list_contact = ''
array_link = ''
array_contact = ''
is_ok = self.is_in_psql(layer)
if is_ok:
exist = self.status_metadata(layer)
if exist:
self.reload_data(layer)
else:
self.new_data(layer)
else:
self.close()
iface.messageBar().pushMessage("Information:", "Cette couche n'est pas stockée dans PostgreSQL", level=Qgis.Warning, duration=30)
def is_in_psql(self, layer):
try:
uri = layer.dataProvider().uri()
except AttributeError:
uri = ''
return False
if uri != '':
if not uri.table():
return False
else:
return True
def status_metadata(self, layer):
uri = layer.dataProvider().uri()
table = uri.table()
schema = uri.schema()
cur = login_base()
count_sql = """ SELECT count(uid) FROM metadata.dataset WHERE table_name LIKE '""" + table + """' AND schema_name LIKE '""" + schema + """';"""
cur.execute(count_sql)
data_count = (cur.fetchall())[0][0]
if data_count == 1:
return True
else:
return False
cur.close()
def new_data(self, layer):
# print(layer.name(),'is new data')
reloader = False
self.interface_view(layer, reloader)
def reload_data(self, layer):
# print(layer.name(),'reload data')
reloader = True
self.interface_view(layer, reloader)
def interface_view(self, layer, reloader):
self.description_text.setText(None)
self.mots_cles_text.setText(None)
self.uuid_ligne.setText(None)
self.niveau_plain.setPlainText(None)
self.echelle_min_plain.setPlainText(None)
self.echelle_max_plain.setPlainText(None)
self.url_line.setText(None)
self.taille_line.setText(None)
self.nom_line.setText(None)
self.email_line.setText(None)
self.telephone_line.setText(None)
self.encodage_box.clear()
self.frequence_box.clear()
self.licence_box.clear()
self.licence_attrib_box.clear()
self.restriction_box.clear()
all_list = self.fletch_ref()
categories_list = all_list[0]
themes_list = all_list[1]
langue_list = all_list[2]
encodage_list = all_list[3]
frequency_list = all_list[4]
confidentiality_list = all_list[5]
license_list = all_list[6]
type_list = all_list[7]
mime_list = all_list[8]
format_list = all_list[9]
role_list = all_list[10]
organisation_list = all_list[11]
# langue_box
self.langue_box.clear()
self.langue_box.addItem('')
# self.langue_box.addItem('Fr')
# self.langue_box.addItem('En')
for langue_list_data in langue_list:
self.langue_box.addItem(langue_list_data[0])
for encodage_list_data in encodage_list:
self.encodage_box.addItem(encodage_list_data[0])
self.table_ligne.setText(layer.dataProvider().uri().table())
self.schema_ligne.setText(layer.dataProvider().uri().schema())
# categories_select_view
self.categories_select_view.setColumnCount(1)
self.categories_select_view.setColumnWidth(0, 230)
self.categories_select_view.setHorizontalHeaderLabels(['List des categories'])
# categories_view
self.categories_view.setRowCount(0)
self.categories_view.setColumnCount(1)
self.categories_view.setColumnWidth(0, 230)
self.categories_view.setHorizontalHeaderLabels(['Categories'])
# themes_select_view
self.themes_select_view.setColumnCount(1)
self.themes_select_view.setColumnWidth(0, 230)
self.themes_select_view.setHorizontalHeaderLabels(['List des thèmes'])
# themes_view
self.themes_view.setRowCount(0)
self.themes_view.setColumnCount(1)
self.themes_view.setColumnWidth(0, 230)
self.themes_view.setHorizontalHeaderLabels(['Thèmes'])
# lien_view
self.table_lien.setRowCount(0)
self.table_lien.setColumnCount(6)
self.table_lien.setColumnWidth(0, 0)
self.table_lien.setHorizontalHeaderLabels(['', 'Type', 'URL', 'MIME', 'Format', 'Taille'])
# contact_view
self.table_contact.setRowCount(0)
self.table_contact.setColumnCount(6)
self.table_contact.setColumnWidth(0, 0)
self.table_contact.setHorizontalHeaderLabels(['', 'Rôle', 'Nom', 'Organisation', 'Email', 'Telephone'])
# print(self.date_maj_date.date().toPyDate())
vector_extend = layer.extent()
polygone_extend = QgsGeometry.fromRect(vector_extend).asWkt()
self.extend_plaintext.setPlainText(str(polygone_extend))
qgstype = str(layer.type())[10:]
if qgstype != 'Raster':
count_layers = str(layer.featureCount())
geomtype = QgsWkbTypes.displayString(layer.wkbType())
elif qgstype == 'Raster':
count_layers = str(layer.dataProvider().bandCount())
geomtype = qgstype
self.nbr_layers.setPlainText(count_layers)
self.typegeom_plaintext.setPlainText(geomtype)
crs_name = str(layer.crs().description())
self.crsname_plaintext.setPlainText(crs_name)
crs_code = str(layer.crs().authid())
self.crscode_plaintext.setPlainText(crs_code)
self.frequence_box.addItem('')
self.restriction_box.addItem('')
self.licence_box.addItem('')
self.licence_attrib_box.addItem('')
for frequency_list_data in frequency_list:
self.frequence_box.addItem(frequency_list_data[0])
for confidentiality_list_data in confidentiality_list:
self.restriction_box.addItem(confidentiality_list_data[0])
for license_list_data in license_list:
self.licence_box.addItem(license_list_data[0])
self.type_box.clear()
self.mime_box.clear()
self.format_box.clear()
self.role_box.clear()
self.organisation_box.clear()
self.type_box.addItem('')
self.mime_box.addItem('')
self.format_box.addItem('')
self.role_box.addItem('')
self.organisation_box.addItem('')
for type_list_data in type_list:
self.type_box.addItem(type_list_data[0])
for mime_list_data in mime_list:
self.mime_box.addItem(mime_list_data[0])
for format_list_data in format_list:
self.format_box.addItem(format_list_data[0])
for role_list_data in role_list:
self.role_box.addItem(role_list_data[0])
for organisation_list_data in organisation_list:
self.organisation_box.addItem(organisation_list_data[0])
if reloader:
sql_dataload = self.sql_info(layer.dataProvider().uri())
sql_contactlink = self.sql_infoother(layer.dataProvider().uri())
sql_datalink = sql_contactlink[0]
sql_datacontact = sql_contactlink[1]
# print(sql_dataload)
self.titre_line.setText(sql_dataload[4])
self.date_maj_date.setDateTime(sql_dataload[23])
self.date_publication_date.setDateTime(sql_dataload[11])
self.description_text.setText(sql_dataload[5])
self.mots_cles_text.setText(sql_dataload[7])
array_langue_box = [self.langue_box.itemText(i) for i in range(self.langue_box.count())]
self.langue_box.setCurrentIndex(array_langue_box.index(sql_dataload[26]))
self.uuid_ligne.setText(sql_dataload[1])
self.categories_view.setRowCount(len(sql_dataload[6]))
i = 0
for categorie_data in sql_dataload[6]:
self.categories_view.setItem(i, 0, QTableWidgetItem(categorie_data))
i = i + 1
self.themes_view.setRowCount(len(sql_dataload[24]))
i = 0
for themes_data in sql_dataload[24]:
self.themes_view.setItem(i, 0, QTableWidgetItem(themes_data))
i = i + 1
self.categories_select_view.setRowCount(len(categories_list) - len(sql_dataload[6]))
self.themes_select_view.setRowCount(len(themes_list) - len(sql_dataload[24]))
i = 0
for categorie_select_data in categories_list:
try:
in_index = sql_dataload[6].index(categorie_select_data[0])
in_index = False
except ValueError:
in_index = True
if in_index:
self.categories_select_view.setItem(i, 0, QTableWidgetItem(categorie_select_data[0]))
i = i + 1
i = 0
for themes_select_data in themes_list:
try:
in_index = sql_dataload[24].index(themes_select_data[0])
in_index = False
except ValueError:
in_index = True
if in_index:
self.themes_select_view.setItem(i, 0, QTableWidgetItem(themes_select_data[0]))
i = i + 1
array_encodage_box = [self.encodage_box.itemText(i) for i in range(self.encodage_box.count())]
self.encodage_box.setCurrentIndex(array_encodage_box.index(sql_dataload[27]))
self.niveau_plain.setPlainText(sql_dataload[8])
if str(sql_dataload[9]) == 'None':
value_echelle_min = ''
else:
value_echelle_min = str(sql_dataload[9])
if str(sql_dataload[10]) == 'None':
value_echelle_max = ''
else:
value_echelle_max = str(sql_dataload[10])
self.echelle_min_plain.setPlainText(value_echelle_min)
self.echelle_max_plain.setPlainText(value_echelle_max)
array_frequence_box = [self.frequence_box.itemText(i) for i in range(self.frequence_box.count())]
self.frequence_box.setCurrentIndex(array_frequence_box.index(sql_dataload[12]))
array_licence_box = [self.licence_box.itemText(i) for i in range(self.licence_box.count())]
self.licence_box.setCurrentIndex(array_licence_box.index(sql_dataload[13]))
array_confidentiality_box = [self.restriction_box.itemText(i) for i in range(self.restriction_box.count())]
self.restriction_box.setCurrentIndex(array_confidentiality_box.index(sql_dataload[14]))
array_licence_attrib_box = [self.licence_attrib_box.itemText(i) for i in range(self.licence_attrib_box.count())]
self.licence_attrib_box.setCurrentIndex(array_licence_attrib_box.index(sql_dataload[25]))
c = 0
# self.table_lien.setRowCount(len(sql_datalink))
for lien_data in sql_datalink:
self.table_lien.insertRow(c)
self.table_lien.setItem(c, 0, QTableWidgetItem(lien_data[1]))
self.table_lien.setItem(c, 1, QTableWidgetItem(lien_data[4]))
self.table_lien.setItem(c, 2, QTableWidgetItem(lien_data[5]))
self.table_lien.setItem(c, 3, QTableWidgetItem(lien_data[6]))
self.table_lien.setItem(c, 4, QTableWidgetItem(lien_data[7]))
self.table_lien.setItem(c, 5, QTableWidgetItem(lien_data[8]))
c = c + 1
c = 0
# self.table_contact.setRowCount(len(sql_datacontact))
for contact_data in sql_datacontact:
self.table_contact.insertRow(c)
self.table_contact.setItem(c, 0, QTableWidgetItem(contact_data[1]))
self.table_contact.setItem(c, 1, QTableWidgetItem(contact_data[4]))
self.table_contact.setItem(c, 2, QTableWidgetItem(contact_data[5]))
self.table_contact.setItem(c, 3, QTableWidgetItem(contact_data[6]))
self.table_contact.setItem(c, 4, QTableWidgetItem(contact_data[7]))
self.table_contact.setItem(c, 5, QTableWidgetItem(contact_data[8]))
c = c + 1
else:
# titre_line
self.titre_line.setText(layer.name())
self.langue_box.setCurrentIndex(1)
# date_maj_date
now = QtCore.QDateTime.currentDateTime()
self.date_maj_date.setDateTime(now)
self.date_creation_date.setDateTime(now)
self.date_modification_date.setDateTime(now)
self.date_publication_date.setDateTime(now)
self.categories_select_view.setRowCount(len(categories_list))
self.themes_select_view.setRowCount(len(themes_list))
i = 0
for categorie_select_data in categories_list:
self.categories_select_view.setItem(i, 0, QTableWidgetItem(categorie_select_data[0]))
i = i + 1
i = 0
for themes_select_data in themes_list:
self.themes_select_view.setItem(i, 0, QTableWidgetItem(themes_select_data[0]))
i = i + 1
# print(self.langue_box.currentText())
def sql_info(self, uri):
cur = login_base()
table = uri.table()
schema = uri.schema()
# [s for s in iface.activeLayer().source().split(" ") if "dbname" in s][0].split("'")[1]
sql_find = """SELECT *, right(left(st_astext(geom,2),-2),-9) FROM metadata.dataset
WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
cur.execute(sql_find)
data_general = cur.fetchall()
cur.close()
return data_general[0]
def sql_infoother(self, uri):
cur = login_base()
table = uri.table()
schema = uri.schema()
sql_findlink = """SELECT * FROM metadata.dataurl
WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
cur.execute(sql_findlink)
data_link = cur.fetchall()
sql_findcontact = """SELECT * FROM metadata.datacontact
WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
cur.execute(sql_findcontact)
data_contact = cur.fetchall()
cur.close()
return data_link, data_contact
def add_categories_view(self):
values_add_categories = self.categories_select_view.selectedItems()[0].text()
self.categories_select_view.removeRow(self.categories_select_view.currentRow())
self.categories_view.insertRow(0)
self.categories_view.setItem(0, 0, QTableWidgetItem(values_add_categories))
def deleter_categories_view(self):
values_deleter_categories = self.categories_view.selectedItems()[0].text()
self.categories_view.removeRow(self.categories_view.currentRow())
self.categories_select_view.insertRow(0)
self.categories_select_view.setItem(0, 0, QTableWidgetItem(values_deleter_categories))
def add_themes_view(self):
values_add_themes = self.themes_select_view.selectedItems()[0].text()
self.themes_select_view.removeRow(self.themes_select_view.currentRow())
self.themes_view.insertRow(0)
self.themes_view.setItem(0, 0, QTableWidgetItem(values_add_themes))
def deleter_themes_view(self):
values_deleter_themes = self.themes_view.selectedItems()[0].text()
self.themes_view.removeRow(self.themes_view.currentRow())
self.themes_select_view.insertRow(0)
self.themes_select_view.setItem(0, 0, QTableWidgetItem(values_deleter_themes))
def add_lien(self):
cur = login_base()
maxrow = self.table_lien.rowCount()
self.table_lien.insertRow(maxrow)
table = layer.dataProvider().uri().table()
schema = layer.dataProvider().uri().schema()
if self.taille_line.text() == '':
sql_sizefile = """SELECT pg_size_pretty(pg_total_relation_size('""" + schema + '.' + table + """'));"""
try:
cur.execute(sql_sizefile)
boolean = True
except psycopg2.errors.UndefinedTable:
boolean = False
if boolean is True:
size_file = (cur.fetchall())[0][0]
else:
size_file = ''
else:
size_file = self.taille_line.text()
self.table_lien.setItem(maxrow, 0, QTableWidgetItem('new_value'))
self.table_lien.setItem(maxrow, 1, QTableWidgetItem(self.type_box.currentText()))
self.table_lien.setItem(maxrow, 2, QTableWidgetItem(self.url_line.text()))
self.table_lien.setItem(maxrow, 3, QTableWidgetItem(self.mime_box.currentText()))
self.table_lien.setItem(maxrow, 4, QTableWidgetItem(self.format_box.currentText()))
self.table_lien.setItem(maxrow, 5, QTableWidgetItem(str(size_file)))
global array_link
array_link += "('" + table + "', '" + schema + "', '" + self.type_box.currentText() + "', '" + self.url_line.text() + "', '" + self.mime_box.currentText() + "', '" + self.format_box.currentText() + "', '" + size_file + "'),"
cur.close()
def add_contact(self):
maxrow = self.table_contact.rowCount()
self.table_contact.insertRow(maxrow)
self.table_contact.setItem(maxrow, 0, QTableWidgetItem('new_value'))
self.table_contact.setItem(maxrow, 1, QTableWidgetItem(self.role_box.currentText()))
self.table_contact.setItem(maxrow, 2, QTableWidgetItem(self.nom_line.text()))
self.table_contact.setItem(maxrow, 3, QTableWidgetItem(self.organisation_box.currentText()))
self.table_contact.setItem(maxrow, 4, QTableWidgetItem(self.email_line.text()))
self.table_contact.setItem(maxrow, 5, QTableWidgetItem(self.telephone_line.text()))
table = layer.dataProvider().uri().table()
schema = layer.dataProvider().uri().schema()
global array_contact
array_contact += "('" + table + "', '" + schema + "', '" + self.role_box.currentText() + "', '" + self.nom_line.text() + "', '" + self.organisation_box.currentText() + "', '" + self.email_line.text() + "', '" + self.telephone_line.text() + "'),"
def delete_lien(self):
fin = ''
global uid_delete_list_link, array_link
try:
lien_uid = self.table_lien.item(self.table_lien.currentRow(), 0).text()
except AttributeError:
lien_uid = True
self.table_lien.removeRow(self.table_lien.currentRow())
if lien_uid == 'new_value':
position = self.table_lien.currentRow()
if position < 0:
position = position + 1
run_x = 0
while position >= run_x:
# print(position, run_x)
if run_x == 0:
debut = array_link.find("(")
else:
debut = array_link.find("(", fin + 1)
fin = array_link.find(")", debut)
# print(debut, fin)
if run_x == 50:
break
run_x += 1
# print(array_link[fin + 1:])
if debut <= 0:
debut = 1
fin += 1
array_link = array_link[:debut - 1] + array_link[fin + 1:]
# print('a:', array_link)
elif lien_uid is True:
print('Pas de ligne "Lien"')
else:
uid_delete_list_link += "'" + lien_uid + "',"
def delete_contact(self):
fin = ''
global uid_delete_list_contact, array_contact
try:
contact_uid = self.table_contact.item(self.table_contact.currentRow(), 0).text()
except AttributeError:
contact_uid = True
self.table_contact.removeRow(self.table_contact.currentRow())
if contact_uid == 'new_value':
position = self.table_contact.currentRow()
if position < 0:
position = position + 1
# print('p:', position)
run_x = 0
while position >= run_x:
if run_x == 0:
debut = array_contact.find("(")
else:
debut = array_contact.find("(", fin + 1)
fin = array_contact.find(")", debut)
# print(debut, fin)
if run_x == 50:
break
run_x += 1
# print(array_contact[fin + 1:])
if debut <= 0:
debut = 1
fin += 1
array_contact = array_contact[:debut - 1] + array_contact[fin + 1:]
# print('a:', array_contact)
elif contact_uid is True:
print('Pas de ligne "Contact"')
else:
uid_delete_list_contact += "'" + contact_uid + "',"
def fletch_ref(self):
cur = login_base()
SQL_categories = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.categories' ORDER BY code, item_order;"""
SQL_themes = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.themes' ORDER BY label_fr;"""
SQL_langue = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.langue';"""
SQL_encodage = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.encodage';"""
SQL_frequency = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.publication_frequency' ORDER BY label_fr;"""
SQL_confidentiality = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.confidentiality' ORDER BY label_fr;"""
SQL_license = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.license' ORDER BY label_fr;"""
SQL_type = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'link.type' ORDER BY label_fr;"""
SQL_mime = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'link.mime' ORDER BY label_fr;"""
SQL_format = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'link.format' ORDER BY label_fr;"""
SQL_role = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'contact.contact_role' ORDER BY label_fr;"""
SQL_organisation = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'contact.organisation' ORDER BY label_fr;"""
cur.execute(SQL_categories)
categories_list = cur.fetchall()
cur.execute(SQL_themes)
themes_list = cur.fetchall()
cur.execute(SQL_langue)
langue_list = cur.fetchall()
cur.execute(SQL_encodage)
encodage_list = cur.fetchall()
cur.execute(SQL_frequency)
frequency_list = cur.fetchall()
cur.execute(SQL_confidentiality)
confidentiality_list = cur.fetchall()
cur.execute(SQL_license)
license_list = cur.fetchall()
cur.execute(SQL_type)
type_list = cur.fetchall()
cur.execute(SQL_mime)
mime_list = cur.fetchall()
cur.execute(SQL_format)
format_list = cur.fetchall()
cur.execute(SQL_role)
role_list = cur.fetchall()
cur.execute(SQL_organisation)
organisation_list = cur.fetchall()
return categories_list, themes_list, langue_list, encodage_list, frequency_list, confidentiality_list, license_list, type_list, mime_list, format_list, role_list, organisation_list
cur.close()
def py_import_xml(self):
folder = QFileDialog.getOpenFileName()
if folder:
folder = folder[0]
if folder[len(folder) - 4:] == '.xml':
print('is .xml')
# def issues_open(self):
# self.issues = CenRa_Issues()
# self.issues.show()
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

+89
View File
@@ -0,0 +1,89 @@
import os
plugin_dir = os.path.dirname(__file__)
end_find = plugin_dir.rfind('\\')+1
NAME = plugin_dir[end_find:]
#print(NAME)
from qgis.gui import *
from qgis.core import (
NULL,
QgsApplication,
QgsDataSourceUri,
QgsProject,
QgsProviderConnectionException,
QgsProviderRegistry,
QgsRasterLayer,
QgsSettings,
QgsVectorLayer,
QgsGeometry,
)
from qgis.PyQt.QtWidgets import (
QDialog,
QAction,
QDockWidget,
QFileDialog,
QInputDialog,
QMenu,
QToolButton,
QTableWidget,
QTableWidgetItem,
)
from qgis.utils import iface
from .tools.resources import (
load_ui,
resources_path,
send_issues,
)
EDITOR_CLASS = load_ui('CenRa_IssuesSend.ui')
class CenRa_Issues(QDialog, EDITOR_CLASS):
def __init__(self, parent=None):
_ = parent
super().__init__()
self.setupUi(self)
self.settings = QgsSettings()
#place connect here
self.annuler_button.clicked.connect(self.close)
self.ok_button.clicked.connect(self.run_sendissues)
def run_sendissues(self):
text_titre = self.titre_line.text()
text_message = self.messages_plain.toPlainText()
statu_bug = self.check_bug.isChecked()
statu_aide = self.check_aide.isChecked()
statu_question = self.check_question.isChecked()
statu_amelioration = self.check_amelioration.isChecked()
statu_autre = self.check_autre.isChecked()
statu = []
if statu_bug == True : statu = statu + [1]
if statu_aide == True : statu = statu + [3]
if statu_question == True : statu = statu + [5]
if statu_amelioration == True : statu = statu + [2]
if statu_autre == True : statu = statu + [6]
if len(statu) >= 1:
import qgis
url = qgis.utils.pluginMetadata(NAME,'tracker')
print(text_message)
send_info = send_issues(url,text_titre,text_message,statu)
code = send_info.status_code
print(code)
else:
code = 423
if code == 201:
iface.messageBar().pushMessage("Envoyer :", "Votre messages à bien été envoyer.", level=Qgis.Success, duration=20)
self.close()
elif code == 422:
iface.messageBar().pushMessage("Erreur :", "Erreur dans le contenu du messages.", level=Qgis.Critical, duration=20)
elif code == 423:
iface.messageBar().pushMessage("Erreur :", "Pas de sujet sélectionné.", level=Qgis.Critical, duration=20)
elif code == 404:
iface.messageBar().pushMessage("Missing :", "Le serveur de messagerie est injoignable.", level=Qgis.Warning, duration=20)
+50
View File
@@ -0,0 +1,50 @@
# This file contains metadata for your plugin.
# This file should be included when you package your plugin.# Mandatory items:
[general]
name=CenRa_Metabase
qgisMinimumVersion=3.0
qgisMaximumVersion=4.99
supportsQt6=True
description=CenRa_METABASE
version=0.3.2
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
about=Permet de saisire et de visualisé les information lier à la metadonné d'une couche ce trouvent sur PostgreSQL
repository=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS
homepage=https://plateformesig.cenra-outils.org/
tracker=https://gitea.cenra-outils.org/api/v1/repos/CEN-RA/Plugin_QGIS/issues
# End of mandatory metadata
# Recommended items:
hasProcessingProvider=no
# Uncomment the following line and add your changelog:
changelog=<h2>CenRa_METABASE:</h2></br><p><h3>12/03/2026 - Version 0.3.2: </h3> - qgisMaximumVersion est 4.0.</p></br><p><h3>30/07/2025 - Version 0.3.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 0.3.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>09/04/2025 - Version 0.2.3: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 0.2.2: </h3> - Optimisation pour le TT.</p></br><p><h3>03/04/2025 - Version 0.2.1: </h3> - Mise a jour de securite.</p></br><p><h3>07/01/2025 - Version 0.2.0: </h3> - Deployment sur serveur SIG.</p></br><p><h3>07/01/2025 - Version 0.1.6: </h3> - ByPass du certif ssl ci erreur</p></br><p><h3>19/12/2024 - Version 0.1.5: </h3> - Fix les problem de lenteur qu'en la base est down.</p></br><p><h3>12/12/2024 - Version 0.1.4: </h3> - Crash Fix .</p></br><p><h3>08/10/2024 - Version 0.1.3: </h3> - Lecture de métadonnée des flux WMS/WFS.</p></br><p><h3>07/10/2024 - Version 0.1.2: </h3> - Correctif de bug.</p></br><p><h3>03/10/2024 - Version 0.1.1: </h3> - Remonte la fênetre dans la pille.</p></br><p><h3>26/08/2024 - Version 0.1.0: </h3> - Lancement du plugin CenRa_Metabase </p>
# Tags are comma separated with spaces allowed
tags=python
category=Plugins
icon=icon.png
# experimental flag
experimental=True
# deprecated flag (applies to the whole plugin, not just a single version)
deprecated=False
# Since QGIS 3.8, a comma separated list of plugins to be installed
# (or upgraded) can be specified.
# Check the documentation for more information.
# plugin_dependencies=
Category of the plugin: Raster, Vector, Database or Web
# category=cenra,database,metadata
# If the plugin can run on QGIS Server.
server=False
+61
View File
@@ -0,0 +1,61 @@
body {
font-family: Ubuntu, Lucida Grande, Segoe UI, Arial, sans-serif;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
font-size: 14px;
}
img {
max-width: 100%;
}
img.logo{
display: inline-block;
margin-left:0px;
margin-right: 0px;
margin-top: 10px;
margin-bottom: 10px;
vertical-align: top;
width:25%
}
h2, h3 {
color: #fff;
background-color: #8cb63c;
line-height: 2;
padding-left:5px;
}
table {
border-collapse: collapse;
width: 100%;
font-size: 13px;
}
th{
color: #2c4491
}
table tr th, table tr td {
text-align: left;
padding: 5px;
}
table.table-striped {
border: 1px solid #BBB;
}
table.table-striped tr td {
border: 1px solid #BBB;
}
table.table-striped tr th {
border: 1px solid #BBB;
}
table.table-striped tr:nth-child(even) {
background: #EEE;
}
table.table-striped tr:nth-child(odd) {
background: #FFF;
}
#map {
padding: 5px;
width: 400px;
height: 400px;
box-shadow: 0 0 10px #999;
}
+7
View File
@@ -0,0 +1,7 @@
<tr>
<td>[% contact_role %]</td>
<td>[% name %]</td>
<td>[% organisation_name %] ([% organisation_unit %])</td>
<td><a href="mailto:[% email %]">[% email %]</a></td>
<td>[% phone %]</td>
</tr>
+7
View File
@@ -0,0 +1,7 @@
<tr>
<td><span title="[% type_label %]">[% type %]</span></td>
<td><a title="[% description %]" href="[% url %]" target="_blank">[% name %]</a></td>
<td><span title="[% mime_label %]">[% mime %]</span></td>
<td>[% format %]</td>
<td>[% size %]</td>
</tr>
+123
View File
@@ -0,0 +1,123 @@
<div>
<h3>Identification</h3>
<table class="table table-condensed">
<tr>
<th>Title</th><td>[% title %]</td>
</tr>
<tr>
<th>Abstract</th><td>[% abstract %]</td>
</tr>
<tr>
<th>Categories</th><td>[% categories %]</td>
</tr>
<tr>
<th>Themes</th><td>[% themes %]</td>
</tr>
<tr>
<th>Keywords</th><td>[% keywords %]</td>
</tr>
<tr>
<th>Data last update</th><td>[% data_last_update %]</td>
</tr>
</table>
</div>
<div>
<h3>Spatial properties</h3>
<table class="table table-condensed">
<tr>
<th>Level</th><td>[% spatial_level %]</td>
</tr>
<tr>
<th>Minimum scale</th><td>[% minimum_optimal_scale %]</td>
</tr>
<tr>
<th>Maximum scale</th><td>[% maximum_optimal_scale %]</td>
</tr>
<tr>
<th>Feature count</th><td>[% feature_count %]</td>
</tr>
<tr>
<th>Geometry</th><td>[% geometry_type %]</td>
</tr>
<tr>
<th>Extent</th><td>[% spatial_extent %]</td>
</tr>
<tr>
<th>Projection name</th><td>[% projection_name %]</td>
</tr>
<tr>
<th>Projection ID</th><td>[% projection_authid %]</td>
</tr>
</table>
</div>
<div>
<h3>Publication</h3>
<table class="table table-condensed">
<tr>
<th>Date</th><td>[% publication_date %]</td>
</tr>
<tr>
<th>Frequency</th><td>[% publication_frequency %]</td>
</tr>
<tr>
<th>License</th><td>[% license %]</td>
</tr>
<tr>
<th>License attribution / number</th><td>[% license_attribution %]</td>
</tr>
<tr>
<th>Confidentiality</th><td>[% confidentiality %]</td>
</tr>
</table>
</div>
<div>
<h3>Links</h3>
<table class="table table-condensed table-striped table-bordered">
<tr>
<th>Type</th>
<th>Name</th>
<th>MIME</th>
<th>Format</th>
<th>Size</th>
</tr>
[% meta_links %]
</table>
</div>
<div>
<h3>Contacts</h3>
<table class="table table-condensed table-striped table-bordered">
<tr>
<th>Role</th>
<th>Name</th>
<th>Organisation</th>
<th>Email</th>
<th>Phone</th>
</tr>
[% meta_contacts %]
</table>
</div>
<div>
<h3>Metadata</h3>
<table class="table table-condensed">
<tr>
<th>Table</th><td>[% table_name %]</td>
</tr>
<tr>
<th>Schema</th><td>[% schema_name %]</td>
</tr>
<tr>
<th>Creation</th><td>[% creation_date %]</td>
</tr>
<tr>
<th>Update</th><td>[% update_date %]</td>
</tr>
<tr>
<th>UUID</th><td>[% uid %]</td>
</tr>
</table>
</div>
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

+184
View File
@@ -0,0 +1,184 @@
"""Tools to work with resource files."""
import configparser
import shutil
import tempfile
# import base64
# import psycopg2
# import psycopg2.extras
import os
from os.path import abspath, join, pardir, dirname
from qgis.PyQt import uic
__copyright__ = "Copyright 2019, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
__revision__ = "$Format:%H$"
def plugin_path(*args):
"""Get the path to plugin root folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the plugin path.
:rtype: str
"""
path = dirname(dirname(__file__))
path = abspath(abspath(join(path, pardir)))
for item in args:
path = abspath(join(path, item))
return path
def plugin_name():
"""Return the plugin name according to metadata.txt.
:return: The plugin name.
:rtype: basestring
"""
metadata = metadata_config()
name = metadata["general"]["name"]
return name
def metadata_config() -> configparser:
"""Get the INI config parser for the metadata file.
:return: The config parser object.
:rtype: ConfigParser
"""
path = plugin_path("metadata.txt")
config = configparser.ConfigParser()
config.read(path, encoding='utf8')
return config
def plugin_test_data_path(*args, copy=False):
"""Get the path to the plugin test data path.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:param copy: If the file must be copied into a temporary directory first.
:type copy: bool
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "test", "data")))
for item in args:
path = abspath(join(path, item))
if copy:
temp = tempfile.mkdtemp()
shutil.copy(path, temp)
return join(temp, args[-1])
else:
return path
def resources_path(*args):
"""Get the path to our resources folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "CenRa_METABASE\\tools")))
for item in args:
path = abspath(join(path, item))
return path
def load_ui(*args):
"""Get compile UI file.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Compiled UI file.
"""
ui_class, _ = uic.loadUiType(resources_path("ui", *args))
return ui_class
def pyperclip():
dst = dirname(dirname(__file__)) + "\\tools\\"
if os.access('N:/', os.R_OK):
src = 'N:/SI_Systeme d information/Z_QGIS/PLUGIN/PythonSQL.py'
try:
shutil.copy(src, dst)
except FileNotFoundError:
print('404')
except UnboundLocalError:
print('404')
def send_issues(url, titre, body, labels):
import requests
import urllib.request
import json
# import os
# import qgis
# usr = os.environ['USERNAME']
token = '9d0a4e0bea561710e0728f161f7edf4e5201e112'
url = url + '?token=' + token
headers = {'Authorization': 'token ' + token, 'accept': 'application/json', 'Content-Type': 'application/json'}
payload = {'title': titre, 'body': body, 'labels': labels}
try:
urllib.request.urlopen('https://google.com')
binar = True
except ValueError:
binar = False
r = ''
if binar:
r = requests.post(url, data=json.dumps(payload), headers=headers)
return r
def maj_verif(NAME):
import qgis
import urllib.request
iface = qgis.utils.iface
from qgis.core import Qgis
# url = qgis.utils.pluginMetadata(NAME, 'repository')
# URL = url+'/raw/branch/main/plugins.xml'
URL = 'https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/plugins.xml'
# print(URL)
version = qgis.utils.pluginMetadata(NAME, 'version')
len_version = len(version)
try:
urllib.request.urlopen('https://google.com')
binar = True
except urllib.error.URLError:
binar = False
if binar:
try:
version_web = str(urllib.request.urlopen(URL).read())
plugin_num = version_web.find(NAME)
valeur_version_web = version_web.find('<version>', plugin_num) + 9
version_plugin = version_web[valeur_version_web:valeur_version_web + len_version]
if version_plugin != version:
iface.messageBar().pushMessage("MAJ :", "Des mise à jour de plugin sont disponibles.", level=Qgis.Info, duration=30)
except urllib.error.URLError:
print("error gitea version ssl")
else:
iface.messageBar().pushMessage("WiFi :", "Pas de connection à internet.", level=Qgis.Warning, duration=30)
def devlog(NAME):
import qgis
devmaj = '<head><style>* {margin:0; padding:0; }</style></head>'
devmaj = devmaj + qgis.utils.pluginMetadata(NAME, 'changelog')
return devmaj
+332
View File
@@ -0,0 +1,332 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CenRa_IssuesSend</class>
<widget class="QDialog" name="CenRa_IssuesSend">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>810</width>
<height>587</height>
</rect>
</property>
<property name="windowTitle">
<string>CEN-RA Metabase</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>icon.svg</normaloff>icon.svg</iconset>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>550</y>
<width>811</width>
<height>31</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="2">
<widget class="QPushButton" name="annuler_button">
<property name="text">
<string>Annuler</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="ok_button">
<property name="text">
<string>Envoyer</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>791</width>
<height>531</height>
</rect>
</property>
<property name="title">
<string>Issues</string>
</property>
<widget class="QLineEdit" name="titre_line">
<property name="geometry">
<rect>
<x>240</x>
<y>40</y>
<width>321</width>
<height>41</height>
</rect>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPlainTextEdit" name="messages_plain">
<property name="geometry">
<rect>
<x>10</x>
<y>101</y>
<width>571</width>
<height>421</height>
</rect>
</property>
</widget>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>589</x>
<y>100</y>
<width>191</width>
<height>431</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>341</width>
<height>411</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
</property>
<item row="0" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="check_bug">
<property name="text">
<string>Bug</string>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="check_aide">
<property name="text">
<string>Aide</string>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="check_question">
<property name="text">
<string>Question</string>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="check_amelioration">
<property name="text">
<string>Amélioration</string>
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="check_autre">
<property name="text">
<string>Autre</string>
</property>
</widget>
</item>
<item row="6" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>250</x>
<y>20</y>
<width>51</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Titre:</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>20</x>
<y>70</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Messages:</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>600</x>
<y>70</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Sujet:</string>
</property>
</widget>
</widget>
</widget>
<tabstops>
<tabstop>ok_button</tabstop>
<tabstop>annuler_button</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CenRa_MetabaseDockWidgetBase</class>
<widget class="QDockWidget" name="CenRa_MetabaseDockWidgetBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>329</width>
<height>515</height>
</rect>
</property>
<property name="windowTitle">
<string>CenRa MetaBase</string>
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="save_button">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="config">
<property name="text">
<string notr="true">...</string>
</property>
<property name="arrowType">
<enum>Qt::NoArrow</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="flatten_dataset_table">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="external_help">
<property name="text">
<string notr="true">help</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTextBrowser" name="viewer"/>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CenRa_Metabase_editorwidget_base</class>
<widget class="QDialog" name="CenRa_about_base">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>471</width>
<height>594</height>
</rect>
</property>
<property name="windowTitle">
<string>Journal des modifications</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>453</width>
<height>547</height>
</rect>
</property>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>451</width>
<height>541</height>
</rect>
</property>
<property name="title">
<string>DevLog</string>
</property>
<widget class="QTextBrowser" name="viewer">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>431</width>
<height>511</height>
</rect>
</property>
</widget>
</widget>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" ?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dct="http://purl.org/dc/terms/"
xmlns:dcat="http://www.w3.org/ns/dcat#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:adms="http://www.w3.org/ns/adms#"
xmlns:vcard="http://www.w3.org/2006/vcard/ns#"
xmlns:schema="http://schema.org/"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<dcat:Catalog>
<dct:description>CEN-RA DCAT RDF catalog</dct:description>
<dct:language>{language}</dct:language>
<dct:title>CEN-RA Metadata</dct:title>
<dcat:dataset>
<dcat:Dataset>
{content}
</dcat:Dataset>
</dcat:dataset>
</dcat:Catalog>
</rdf:RDF>
@@ -0,0 +1,9 @@
<dcat:distribution>
<dcat:Distribution>
<dct:title></dct:title>
<dcat:downloadURL></dcat:downloadURL>
<dcat:mediaType></dcat:mediaType>
<dct:format></dct:format>
<dct:bytesize></dct:bytesize>
</dcat:Distribution>
</dcat:distribution>
+6
View File
@@ -0,0 +1,6 @@
<dct:publisher>
<foaf:Organization>
<foaf:name></foaf:name>
<foaf:mbox></foaf:mbox>
</foaf:Organization>
</dct:publisher>
+141
View File
@@ -0,0 +1,141 @@
__copyright__ = "Copyright 2021, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
from qgis.core import QgsApplication
from qgis.PyQt.QtCore import QUrl, QSettings
from qgis.PyQt.QtGui import QDesktopServices, QIcon
from qgis.PyQt.QtWidgets import QAction
from qgis.utils import iface
import qgis
# include <QSettings>
'''
from pg_metadata.connection_manager import (
store_connections,
validate_connections_names,
)
from pg_metadata.locator import LocatorFilter
from pg_metadata.processing.provider import PgMetadataProvider
from pg_metadata.qgis_plugin_tools.tools.custom_logging import setup_logger
'''
import os
from .tools.resources import (
# plugin_path,
resources_path,
maj_verif,
)
from .canvas_editor import PageRender_Editor
from .about_form import AboutDialog
class PgPageRender:
def __init__(self):
""" Constructor. """
self.canvas_editor = None
# self.issues = None
self.provider = None
self.locator_filter = None
self.dock_action = None
self.help_action = None
plugin_dir = os.path.dirname(__file__)
end_find = plugin_dir.rfind('\\') + 1
global NAME
NAME = plugin_dir[end_find:]
maj_verif(NAME)
# Display About window on first use
version = qgis.utils.pluginMetadata('CenRa_PAGERENDER', 'version')
s = QSettings()
versionUse = s.value("pagerender/version", 1, type=str)
if str(versionUse) != str(version):
s.setValue("pagerender/version", str(version))
print(versionUse, version)
self.open_about_dialog()
def initGui(self):
""" Build the plugin GUI. """
self.toolBar = iface.addToolBar("CenRa_PAGERENDER")
self.toolBar.setObjectName("CenRa_PAGERENDER")
icon = QIcon(resources_path('icons', 'icon.png'))
# Open the online help
self.help_action = QAction(icon, 'CenRa_PAGERENDER', iface.mainWindow())
iface.pluginHelpMenu().addAction(self.help_action)
self.help_action.triggered.connect(self.open_help)
if not self.canvas_editor:
self.canvas_editor = PageRender_Editor()
self.pagerender_action = QAction(icon, 'CenRa_PAGERENDER', None)
self.toolBar.addAction(self.pagerender_action)
self.pagerender_action.triggered.connect(self.open_editor)
'''
if not self.locator_filter:
self.locator_filter = LocatorFilter(iface)
iface.registerLocatorFilter(self.locator_filter)
@staticmethod
def check_invalid_connection_names():
""" Check for invalid connection names in the QgsSettings. """
valid, invalid = validate_connections_names()
n_invalid = len(invalid)
if n_invalid == 0:
return
invalid_text = ', '.join(invalid)
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setWindowTitle(tr('PgMetadata: Database connection(s) not available'))
msg.setText(tr(
f'{n_invalid} connection(s) listed in PgMetadata’s settings are invalid or '
f'no longer available: {invalid_text}'))
msg.setInformativeText(tr(
'Do you want to remove these connection(s) from the PgMetadata settings? '
'(You can also do this later with the “Set Connections” tool.)'))
msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
clicked = msg.exec()
if clicked == QMessageBox.Yes:
iface.messageBar().pushSuccess('PgMetadata', tr(f'{n_invalid} invalid connection(s) removed.'))
store_connections(valid)
if clicked == QMessageBox.No:
iface.messageBar().pushInfo('PgMetadata', tr(f'Keeping {n_invalid} invalid connections.'))
'''
def open_about_dialog(self):
"""
About dialog
"""
dialog = AboutDialog(iface)
dialog.exec()
def open_help():
""" Open the online help. """
QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
def open_editor(self):
self.canvas_editor.show()
self.canvas_editor.raise_()
def unload(self):
""" Unload the plugin. """
if self.canvas_editor:
iface.removePluginMenu('CenRa_PAGERENDER', self.pagerender_action)
if self.provider:
QgsApplication.processingRegistry().removeProvider(self.provider)
del self.provider
if self.locator_filter:
iface.deregisterLocatorFilter(self.locator_filter)
del self.locator_filter
if self.help_action:
iface.pluginHelpMenu().removeAction(self.help_action)
del self.help_action
+1
View File
@@ -0,0 +1 @@
# CenRa_AutoMap
+10
View File
@@ -0,0 +1,10 @@
__copyright__ = "Copyright 2021, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
# noinspection PyPep8Naming
def classFactory(iface): # pylint: disable=invalid-name
_ = iface
from CenRa_PAGERENDER.CenRa_PageRender import PgPageRender
return PgPageRender()
+46
View File
@@ -0,0 +1,46 @@
import os.path
from pathlib import Path
from qgis.PyQt import uic
# from qgis.PyQt.QtGui import QPixmap
from qgis.PyQt.QtWidgets import QDialog
from .tools.resources import devlog
ABOUT_FORM_CLASS, _ = uic.loadUiType(
os.path.join(
str(Path(__file__).resolve().parent),
'tools/ui',
'CenRa_about_form.ui'
)
)
class AboutDialog(QDialog, ABOUT_FORM_CLASS):
""" About - Let the user display the about dialog. """
def __init__(self, iface, parent=None):
super().__init__(parent)
self.iface = iface
self.setupUi(self)
self.viewer.setHtml(devlog('CenRa_PAGERENDER'))
self.rejected.connect(self.onReject)
self.buttonBox.rejected.connect(self.onReject)
self.buttonBox.accepted.connect(self.onAccept)
def onAccept(self):
"""
Save options when pressing OK button
"""
self.accept()
def onReject(self):
"""
Run some actions when
the user closes the dialog
"""
self.close()
+169
View File
@@ -0,0 +1,169 @@
from qgis.core import (
QgsLayoutSize,
QgsUnitTypes,
QgsLayoutPoint,
)
def fletch_canvas(self):
if self.radioButton_6.isChecked():
values_page = 'A4'
else:
values_page = 'A3'
if self.radioButton_7.isChecked():
page_rotate = 'Portrait'
else:
page_rotate = 'Landscape'
if page_rotate == 'Portrait':
if values_page == 'A4':
self.template_parameters['Carte_size'] = QgsLayoutSize(200.0, 200, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_locals'] = QgsLayoutPoint(6, 6, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_rotate'] = 0
self.template_parameters['Carte_2_size'] = QgsLayoutSize(85.71428571428571, 69, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_2_locals'] = QgsLayoutPoint(209, 3, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_2_rotate'] = 0
self.template_parameters['Legande_size'] = QgsLayoutSize(85.71428571428571, 131, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Legande_locals'] = QgsLayoutPoint(209, 74, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Legande_rotate'] = 0
self.template_parameters['Arrow_size'] = QgsLayoutSize(14.285714285714286, 14, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Arrow_locals'] = QgsLayoutPoint(189, 20, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Arrow_rotate'] = 0
self.template_parameters['Echelle_size'] = QgsLayoutSize(51.42857142857143, 7, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_locals'] = QgsLayoutPoint(9, 197, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_rotate'] = 0
self.template_parameters['Logo_size'] = QgsLayoutSize(45.714285714285715, 11, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_locals'] = QgsLayoutPoint(3, 3, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_rotate'] = 0
self.template_parameters['Titre_size'] = QgsLayoutSize(154.28571428571428, 11, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Titre_locals'] = QgsLayoutPoint(51, 3, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Titre_rotate'] = 0
self.template_parameters['Credit_size'] = QgsLayoutSize(51.42857142857143, 6, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Credit_locals'] = QgsLayoutPoint(151, 197, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Credit_rotate'] = 0
self.template_parameters['Source_size'] = QgsLayoutSize(51.42857142857143, 6, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Source_locals'] = QgsLayoutPoint(229, 197, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Source_rotate'] = 0
self.template_parameters['Sous_titre_size'] = QgsLayoutSize(125.71428571428571, 14, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Sous_titre_locals'] = QgsLayoutPoint(60, 20, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Sous_titre_rotate'] = 0
self.template_parameters['Echelle_2_size'] = QgsLayoutSize(51.42857142857143, 13, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_2_locals'] = QgsLayoutPoint(9, 184, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_2_rotate'] = 0
self.template_parameters['Logo_2_size'] = QgsLayoutSize(28.571428571428573, 29, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_2_locals'] = QgsLayoutPoint(9, 151, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_2_rotate'] = 0
if values_page == 'A3':
self.template_parameters['Carte_size'] = QgsLayoutSize(282, 282, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_locals'] = QgsLayoutPoint(8, 8, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_rotate'] = 0
self.template_parameters['Carte_2_size'] = QgsLayoutSize(121, 97, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_2_locals'] = QgsLayoutPoint(294, 4, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_2_rotate'] = 0
self.template_parameters['Legande_size'] = QgsLayoutSize(121, 185, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Legande_locals'] = QgsLayoutPoint(294, 105, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Legande_rotate'] = 0
self.template_parameters['Arrow_size'] = QgsLayoutSize(20, 20, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Arrow_locals'] = QgsLayoutPoint(266, 28, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Arrow_rotate'] = 0
self.template_parameters['Echelle_size'] = QgsLayoutSize(73, 10, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_locals'] = QgsLayoutPoint(12, 278, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_rotate'] = 0
self.template_parameters['Logo_size'] = QgsLayoutSize(64, 16, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_locals'] = QgsLayoutPoint(4, 4, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_rotate'] = 0
self.template_parameters['Titre_size'] = QgsLayoutSize(218, 16, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Titre_locals'] = QgsLayoutPoint(73, 4, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Titre_rotate'] = 0
self.template_parameters['Credit_size'] = QgsLayoutSize(73, 8, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Credit_locals'] = QgsLayoutPoint(214, 278, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Credit_rotate'] = 0
self.template_parameters['Source_size'] = QgsLayoutSize(73, 8, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Source_locals'] = QgsLayoutPoint(322, 278, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Source_rotate'] = 0
self.template_parameters['Sous_titre_size'] = QgsLayoutSize(177, 20, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Sous_titre_locals'] = QgsLayoutPoint(85, 28, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Sous_titre_rotate'] = 0
self.template_parameters['Echelle_2_size'] = QgsLayoutSize(73, 18, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_2_locals'] = QgsLayoutPoint(12, 260, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_2_rotate'] = 0
self.template_parameters['Logo_2_size'] = QgsLayoutSize(40, 40, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_2_locals'] = QgsLayoutPoint(12, 214, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_2_rotate'] = 0
if page_rotate == 'Landscape':
if values_page == 'A4':
self.template_parameters['Carte_size'] = QgsLayoutSize(200.0, 200, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_locals'] = QgsLayoutPoint(6, 6, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_rotate'] = 0
self.template_parameters['Carte_2_size'] = QgsLayoutSize(85.71428571428571, 69, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_2_locals'] = QgsLayoutPoint(209, 3, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_2_rotate'] = 0
self.template_parameters['Legande_size'] = QgsLayoutSize(85.71428571428571, 131, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Legande_locals'] = QgsLayoutPoint(209, 74, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Legande_rotate'] = 0
self.template_parameters['Arrow_size'] = QgsLayoutSize(14.285714285714286, 14, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Arrow_locals'] = QgsLayoutPoint(189, 20, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Arrow_rotate'] = 0
self.template_parameters['Echelle_size'] = QgsLayoutSize(51.42857142857143, 7, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_locals'] = QgsLayoutPoint(9, 197, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_rotate'] = 0
self.template_parameters['Logo_size'] = QgsLayoutSize(45.714285714285715, 11, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_locals'] = QgsLayoutPoint(3, 3, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_rotate'] = 0
self.template_parameters['Titre_size'] = QgsLayoutSize(154.28571428571428, 11, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Titre_locals'] = QgsLayoutPoint(51, 3, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Titre_rotate'] = 0
self.template_parameters['Credit_size'] = QgsLayoutSize(51.42857142857143, 6, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Credit_locals'] = QgsLayoutPoint(151, 197, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Credit_rotate'] = 0
self.template_parameters['Source_size'] = QgsLayoutSize(51.42857142857143, 6, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Source_locals'] = QgsLayoutPoint(229, 197, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Source_rotate'] = 0
self.template_parameters['Sous_titre_size'] = QgsLayoutSize(125.71428571428571, 14, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Sous_titre_locals'] = QgsLayoutPoint(60, 20, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Sous_titre_rotate'] = 0
self.template_parameters['Echelle_2_size'] = QgsLayoutSize(51.42857142857143, 13, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_2_locals'] = QgsLayoutPoint(9, 184, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_2_rotate'] = 0
self.template_parameters['Logo_2_size'] = QgsLayoutSize(28.571428571428573, 29, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_2_locals'] = QgsLayoutPoint(9, 151, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_2_rotate'] = 0
if values_page == 'A3':
self.template_parameters['Carte_size'] = QgsLayoutSize(282, 282, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_locals'] = QgsLayoutPoint(8, 8, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_rotate'] = 0
self.template_parameters['Carte_2_size'] = QgsLayoutSize(121, 97, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_2_locals'] = QgsLayoutPoint(294, 4, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Carte_2_rotate'] = 0
self.template_parameters['Legande_size'] = QgsLayoutSize(121, 185, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Legande_locals'] = QgsLayoutPoint(294, 105, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Legande_rotate'] = 0
self.template_parameters['Arrow_size'] = QgsLayoutSize(20, 20, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Arrow_locals'] = QgsLayoutPoint(266, 28, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Arrow_rotate'] = 0
self.template_parameters['Echelle_size'] = QgsLayoutSize(73, 10, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_locals'] = QgsLayoutPoint(12, 278, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_rotate'] = 0
self.template_parameters['Logo_size'] = QgsLayoutSize(64, 16, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_locals'] = QgsLayoutPoint(4, 4, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_rotate'] = 0
self.template_parameters['Titre_size'] = QgsLayoutSize(218, 16, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Titre_locals'] = QgsLayoutPoint(73, 4, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Titre_rotate'] = 0
self.template_parameters['Credit_size'] = QgsLayoutSize(73, 8, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Credit_locals'] = QgsLayoutPoint(214, 278, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Credit_rotate'] = 0
self.template_parameters['Source_size'] = QgsLayoutSize(73, 8, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Source_locals'] = QgsLayoutPoint(322, 278, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Source_rotate'] = 0
self.template_parameters['Sous_titre_size'] = QgsLayoutSize(177, 20, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Sous_titre_locals'] = QgsLayoutPoint(85, 28, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Sous_titre_rotate'] = 0
self.template_parameters['Echelle_2_size'] = QgsLayoutSize(73, 18, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_2_locals'] = QgsLayoutPoint(12, 260, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Echelle_2_rotate'] = 0
self.template_parameters['Logo_2_size'] = QgsLayoutSize(40, 40, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_2_locals'] = QgsLayoutPoint(12, 214, QgsUnitTypes.LayoutMillimeters)
self.template_parameters['Logo_2_rotate'] = 0
return self.template_parameters
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

+89
View File
@@ -0,0 +1,89 @@
import os
plugin_dir = os.path.dirname(__file__)
end_find = plugin_dir.rfind('\\')+1
NAME = plugin_dir[end_find:]
#print(NAME)
from qgis.gui import *
from qgis.core import (
NULL,
QgsApplication,
QgsDataSourceUri,
QgsProject,
QgsProviderConnectionException,
QgsProviderRegistry,
QgsRasterLayer,
QgsSettings,
QgsVectorLayer,
QgsGeometry,
)
from qgis.PyQt.QtWidgets import (
QDialog,
QAction,
QDockWidget,
QFileDialog,
QInputDialog,
QMenu,
QToolButton,
QTableWidget,
QTableWidgetItem,
)
from qgis.utils import iface
from .tools.resources import (
load_ui,
resources_path,
send_issues,
)
EDITOR_CLASS = load_ui('CenRa_IssuesSend.ui')
class CenRa_Issues(QDialog, EDITOR_CLASS):
def __init__(self, parent=None):
_ = parent
super().__init__()
self.setupUi(self)
self.settings = QgsSettings()
#place connect here
self.annuler_button.clicked.connect(self.close)
self.ok_button.clicked.connect(self.run_sendissues)
def run_sendissues(self):
text_titre = self.titre_line.text()
text_message = self.messages_plain.toPlainText()
statu_bug = self.check_bug.isChecked()
statu_aide = self.check_aide.isChecked()
statu_question = self.check_question.isChecked()
statu_amelioration = self.check_amelioration.isChecked()
statu_autre = self.check_autre.isChecked()
statu = []
if statu_bug == True : statu = statu + [1]
if statu_aide == True : statu = statu + [3]
if statu_question == True : statu = statu + [5]
if statu_amelioration == True : statu = statu + [2]
if statu_autre == True : statu = statu + [6]
if len(statu) >= 1:
import qgis
url = qgis.utils.pluginMetadata(NAME,'tracker')
print(text_message)
send_info = send_issues(url,text_titre,text_message,statu)
code = send_info.status_code
print(code)
else:
code = 423
if code == 201:
iface.messageBar().pushMessage("Envoyer :", "Votre messages à bien été envoyer.", level=Qgis.Success, duration=20)
self.close()
elif code == 422:
iface.messageBar().pushMessage("Erreur :", "Erreur dans le contenu du messages.", level=Qgis.Critical, duration=20)
elif code == 423:
iface.messageBar().pushMessage("Erreur :", "Pas de sujet sélectionné.", level=Qgis.Critical, duration=20)
elif code == 404:
iface.messageBar().pushMessage("Missing :", "Le serveur de messagerie est injoignable.", level=Qgis.Warning, duration=20)
+3 -2
View File
@@ -5,9 +5,10 @@
[general]
name=CenRa_PageRender
qgisMinimumVersion=3.0
qgisMaximumVersion=4.99
supportsQt6=True
description=CenRa_PageRender
version=0.2.3
version=0.2.5
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
@@ -22,7 +23,7 @@ tracker=https://gitea.cenra-outils.org/api/v1/repos/CEN-RA/Plugin_QGIS/issues
hasProcessingProvider=no
# Uncomment the following line and add your changelog:
changelog=<h2>CenRa_PAGERENDER:</h2></br><p><h3>15/12/2025 - Version 0.2.3: </h3> - nouveau systeme de parametrage.</p></br><p><h3>12/12/2025 - Version 0.2.2: </h3> - bug sur le background.</p></br><p><h3>30/07/2025 - Version 0.2.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 0.2.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>03/04/2025 - Version 0.1.6: </h3> - Mise a jour de securite.</p></br><p><h3>07/01/2025 - Version 0.1.5: </h3> - ByPass du certif ssl ci erreur.</br></p><p><h3>14/11/2024 - Version 0.1.4: </h3> - Implementation de la mollet. </br> - Implementation du dragging pour déplacer et modification de la taille </br></p></br><p><h3>08/11/2024 - Version 0.1.3: </h3> - Correctif de bug. </br><p><h3>21/10/2024 - Version 0.1.1: </h3> - Les match en if. </br> - Bouton de scroll et adaptation portrait.</p></br><p><h3>09/10/2024 - Version 0.1.0: </h3> - Création.</p>
changelog=<h2>CenRa_PAGERENDER:</h2></br><p><h3>23/03/2026 - Version 0.2.5: </h3> - Pache mineur.</p></br><p><h3>12/03/2026 - Version 0.2.4: </h3> - qgisMaximumVersion est 4.0.</p></br><p><h3>15/12/2025 - Version 0.2.3: </h3> - nouveau systeme de parametrage.</p></br><p><h3>12/12/2025 - Version 0.2.2: </h3> - bug sur le background.</p></br><p><h3>30/07/2025 - Version 0.2.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 0.2.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>03/04/2025 - Version 0.1.6: </h3> - Mise a jour de securite.</p></br><p><h3>07/01/2025 - Version 0.1.5: </h3> - ByPass du certif ssl ci erreur.</br></p><p><h3>14/11/2024 - Version 0.1.4: </h3> - Implementation de la mollet. </br> - Implementation du dragging pour déplacer et modification de la taille </br></p></br><p><h3>08/11/2024 - Version 0.1.3: </h3> - Correctif de bug. </br><p><h3>21/10/2024 - Version 0.1.1: </h3> - Les match en if. </br> - Bouton de scroll et adaptation portrait.</p></br><p><h3>09/10/2024 - Version 0.1.0: </h3> - Création.</p>
# Tags are comma separated with spaces allowed
tags=python
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

+174
View File
@@ -0,0 +1,174 @@
"""Tools to work with resource files."""
import configparser
import shutil
import tempfile
# import base64
# import psycopg2
# import psycopg2.extras
from os.path import abspath, join, pardir, dirname
from qgis.PyQt.QtWidgets import QApplication
from qgis.PyQt import uic
__copyright__ = "Copyright 2019, 3Liz"
__license__ = "GPL version 3"
__email__ = "info@3liz.org"
__revision__ = "$Format:%H$"
def plugin_path(*args):
"""Get the path to plugin root folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the plugin path.
:rtype: str
"""
path = dirname(dirname(__file__))
path = abspath(abspath(join(path, pardir)))
for item in args:
path = abspath(join(path, item))
return path
def plugin_name():
"""Return the plugin name according to metadata.txt.
:return: The plugin name.
:rtype: basestring
"""
metadata = metadata_config()
name = metadata["general"]["name"]
return name
def metadata_config() -> configparser:
"""Get the INI config parser for the metadata file.
:return: The config parser object.
:rtype: ConfigParser
"""
path = plugin_path("metadata.txt")
config = configparser.ConfigParser()
config.read(path, encoding='utf8')
return config
def plugin_test_data_path(*args, copy=False):
"""Get the path to the plugin test data path.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:param copy: If the file must be copied into a temporary directory first.
:type copy: bool
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "test", "data")))
for item in args:
path = abspath(join(path, item))
if copy:
temp = tempfile.mkdtemp()
shutil.copy(path, temp)
return join(temp, args[-1])
else:
return path
def resources_path(*args):
"""Get the path to our resources folder.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "CenRa_PAGERENDER\\tools")))
for item in args:
path = abspath(join(path, item))
return path
def load_ui(*args):
"""Get compile UI file.
:param args List of path elements e.g. ['img', 'logos', 'image.png']
:type args: str
:return: Compiled UI file.
"""
ui_class, _ = uic.loadUiType(resources_path("ui", *args))
return ui_class
def send_issues(url, titre, body, labels):
import requests
import urllib.request
import json
# import os
# usr = os.environ['USERNAME']
token = '9d0a4e0bea561710e0728f161f7edf4e5201e112'
url = url + '?token=' + token
headers = {'Authorization': 'token ' + token, 'accept': 'application/json', 'Content-Type': 'application/json'}
payload = {'title': titre, 'body': body, 'labels': labels}
try:
urllib.request.urlopen('https://google.com')
binar = True
except urllib.requests.URLError:
binar = False
r = ''
if binar:
r = requests.post(url, data=json.dumps(payload), headers=headers)
return r
def maj_verif(NAME):
import qgis
import urllib.request
iface = qgis.utils.iface
from qgis.core import Qgis
# url = qgis.utils.pluginMetadata(NAME, 'repository')
# URL = url+'/raw/branch/main/plugins.xml'
URL = 'https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/plugins.xml'
# print(URL)
version = qgis.utils.pluginMetadata(NAME, 'version')
len_version = len(version)
try:
urllib.request.urlopen('https://google.com')
binar = True
except urllib.error.URLError:
binar = False
if binar:
try:
version_web = str(urllib.request.urlopen(URL).read())
plugin_num = version_web.find(NAME)
valeur_version_web = version_web.find('<version>', plugin_num) + 9
version_plugin = version_web[valeur_version_web:valeur_version_web + len_version]
if version_plugin != version:
iface.messageBar().pushMessage("MAJ :", "Des mise à jour de plugin sont disponibles.", level=Qgis.Info, duration=30)
except urllib.requests.URLError:
print("error gitea version ssl")
else:
iface.messageBar().pushMessage("WiFi :", "Pas de connection à internet.", level=Qgis.Warning, duration=30)
def tr(text, context="@default"):
return QApplication.translate(context, text)
def devlog(NAME):
import qgis
devmaj = '<head><style>* {margin:0; padding:0; }</style></head>'
devmaj = devmaj + qgis.utils.pluginMetadata(NAME, 'changelog')
return devmaj
@@ -0,0 +1,332 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CenRa_IssuesSend</class>
<widget class="QDialog" name="CenRa_IssuesSend">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>810</width>
<height>587</height>
</rect>
</property>
<property name="windowTitle">
<string>CEN-RA Metabase</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>icon.svg</normaloff>icon.svg</iconset>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>550</y>
<width>811</width>
<height>31</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="2">
<widget class="QPushButton" name="annuler_button">
<property name="text">
<string>Annuler</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="ok_button">
<property name="text">
<string>Envoyer</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>791</width>
<height>531</height>
</rect>
</property>
<property name="title">
<string>Issues</string>
</property>
<widget class="QLineEdit" name="titre_line">
<property name="geometry">
<rect>
<x>240</x>
<y>40</y>
<width>321</width>
<height>41</height>
</rect>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPlainTextEdit" name="messages_plain">
<property name="geometry">
<rect>
<x>10</x>
<y>101</y>
<width>571</width>
<height>421</height>
</rect>
</property>
</widget>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>589</x>
<y>100</y>
<width>191</width>
<height>431</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>341</width>
<height>411</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
</property>
<item row="0" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="check_bug">
<property name="text">
<string>Bug</string>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="check_aide">
<property name="text">
<string>Aide</string>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="check_question">
<property name="text">
<string>Question</string>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="check_amelioration">
<property name="text">
<string>Amélioration</string>
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="check_autre">
<property name="text">
<string>Autre</string>
</property>
</widget>
</item>
<item row="6" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>250</x>
<y>20</y>
<width>51</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Titre:</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>20</x>
<y>70</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Messages:</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>600</x>
<y>70</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Sujet:</string>
</property>
</widget>
</widget>
</widget>
<tabstops>
<tabstop>ok_button</tabstop>
<tabstop>annuler_button</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
@@ -78,7 +78,7 @@
<number>296</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QSlider" name="verticalSlider">
@@ -100,7 +100,7 @@
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
<enum>Qt::Vertical</enum>
</property>
<property name="invertedAppearance">
<bool>true</bool>
@@ -118,12 +118,6 @@
<property name="styleSheet">
<string notr="true">QFrame#frame{background-color: rgb(255, 255, 255, 170);}</string>
</property>
<property name="frameShape">
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
<widget class="QLabel" name="Carte">
<property name="geometry">
<rect>
@@ -139,24 +133,9 @@
<property name="styleSheet">
<string notr="true">background-color: rgba(10, 10, 10, 50)</string>
</property>
<property name="frameShape">
<enum>QFrame::Shape::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Plain</enum>
</property>
<property name="lineWidth">
<number>5</number>
</property>
<property name="midLineWidth">
<number>2</number>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="margin">
<number>5</number>
</property>
@@ -176,9 +155,6 @@
<property name="styleSheet">
<string notr="true">background-color: rgba(10, 10, 10, 50)</string>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Plain</enum>
</property>
<property name="text">
<string/>
</property>
@@ -277,27 +253,12 @@
<property name="styleSheet">
<string notr="true">background-color: rgba(10, 10, 10, 50)</string>
</property>
<property name="frameShape">
<enum>QFrame::Shape::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
<property name="lineWidth">
<number>-1</number>
</property>
<property name="midLineWidth">
<number>0</number>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTop|Qt::AlignmentFlag::AlignTrailing</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
@@ -364,27 +325,12 @@
<property name="styleSheet">
<string notr="true">background-color: rgba(10, 10, 10, 50)</string>
</property>
<property name="frameShape">
<enum>QFrame::Shape::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
<property name="lineWidth">
<number>-1</number>
</property>
<property name="midLineWidth">
<number>0</number>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTop|Qt::AlignmentFlag::AlignTrailing</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
@@ -446,12 +392,6 @@
<property name="styleSheet">
<string notr="true">QFrame#frame_2{background-color: rgb(255, 255, 255, 170);}</string>
</property>
<property name="frameShape">
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
<widget class="QTableWidget" name="tableWidget">
<property name="geometry">
<rect>
@@ -465,13 +405,13 @@
<number>1</number>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOff</enum>
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContentsOnFirstShow</enum>
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
@@ -483,19 +423,19 @@
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDropMode::NoDragDrop</enum>
<enum>QAbstractItemView::NoDragDrop</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::DropAction::IgnoreAction</enum>
<enum>Qt::IgnoreAction</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SelectionMode::SingleSelection</enum>
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectionBehavior::SelectRows</enum>
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="iconSize">
<size>
@@ -504,7 +444,7 @@
</size>
</property>
<property name="textElideMode">
<enum>Qt::TextElideMode::ElideMiddle</enum>
<enum>Qt::ElideLeft</enum>
</property>
<property name="showGrid">
<bool>true</bool>
@@ -590,13 +530,13 @@
<number>1</number>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOff</enum>
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContentsOnFirstShow</enum>
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::EditTrigger::DoubleClicked</set>
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
@@ -608,19 +548,19 @@
<bool>false</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDropMode::NoDragDrop</enum>
<enum>QAbstractItemView::NoDragDrop</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::DropAction::IgnoreAction</enum>
<enum>Qt::IgnoreAction</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SelectionMode::SingleSelection</enum>
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectionBehavior::SelectRows</enum>
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="iconSize">
<size>
@@ -629,7 +569,7 @@
</size>
</property>
<property name="textElideMode">
<enum>Qt::TextElideMode::ElideMiddle</enum>
<enum>Qt::ElideLeft</enum>
</property>
<property name="showGrid">
<bool>true</bool>
@@ -707,16 +647,16 @@
</font>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::NoFocus</enum>
<enum>Qt::NoFocus</enum>
</property>
<property name="layoutDirection">
<enum>Qt::LayoutDirection::LeftToRight</enum>
<enum>Qt::LeftToRight</enum>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="inputMethodHints">
<set>Qt::InputMethodHint::ImhNone</set>
<set>Qt::ImhNone</set>
</property>
<property name="text">
<string/>
@@ -741,7 +681,7 @@
</rect>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
<enum>QAbstractSpinBox::UpDownArrows</enum>
</property>
<property name="suffix">
<string/>
@@ -763,7 +703,7 @@
</rect>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
<enum>QAbstractSpinBox::UpDownArrows</enum>
</property>
<property name="suffix">
<string/>
@@ -812,9 +752,6 @@
<property name="value">
<number>40</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="invertedAppearance">
<bool>true</bool>
</property>
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CenRa_Metabase_editorwidget_base</class>
<widget class="QDialog" name="CenRa_about_base">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>471</width>
<height>594</height>
</rect>
</property>
<property name="windowTitle">
<string>Journal des modifications</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>453</width>
<height>547</height>
</rect>
</property>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>451</width>
<height>541</height>
</rect>
</property>
<property name="title">
<string>DevLog</string>
</property>
<widget class="QTextBrowser" name="viewer">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>431</width>
<height>511</height>
</rect>
</property>
</widget>
</widget>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

+10 -14
View File
@@ -25,10 +25,12 @@ from .tools.resources import (
)
pyperclip()
from .postgis_editor import Postgis_Editor
from .postgis_creator import Postgis_Creator
from .postgis_rename import Postgis_Rename
try:
from .postgis_editor import Postgis_Editor
from .postgis_creator import Postgis_Creator
from .postgis_rename import Postgis_Rename
except NameError:
print('Module introuvable...')
IPAddr = socket.gethostbyname(socket.gethostname())
@@ -101,19 +103,13 @@ class PgPostgis:
self.postgis_rename = QAction(icon3, 'dossier_rename', None)
self.toolBar.addAction(self.postgis_rename)
self.postgis_rename.triggered.connect(self.open_rename)
self.postgis_rename.setEnabled(False)
self.postgis_rename.setVisible(0)
if os.environ['USERNAME'] == 'tlaveille' or os.environ['USERNAME'] == 'lpoulin' or os.environ['USERNAME'] == 'rclement':
self.action_rename.setEnabled(True)
self.postgis_rename.setEnabled(True)
if os.access('N:/', os.R_OK):
self.postgis_rename.setEnabled(True)
self.postgis_rename.setVisible(1)
else:
self.action_rename.setEnabled(False)
self.postgis_rename.setEnabled(False)
self.postgis_rename.setVisible(0)
self.postgis_rename.setEnabled(False)
if os.access('N:/', os.R_OK):
self.postgis_rename.setEnabled(True)
def open_about_dialog(self):
"""
+3 -2
View File
@@ -11,9 +11,10 @@
[general]
name=CenRa_POSTGIS
qgisMinimumVersion=3.0
qgisMaximumVersion=4.99
supportsQt6=True
description=Permet de crée un dossier dans la base PostGis
version=3.1
version=3.4
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
@@ -22,7 +23,7 @@ email=si_besoin@cen-rhonealpes.fr
# Optional items:
# Uncomment the following line and add your changelog entries:
changelog=<h2>CenRa_POSTGIS:</h2></br><p><h3>30/07/2025 - Version 3.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 3.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>09/04/2025 - Version 2.9: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 2.8: </h3> - Optimisation pour le TT.</p></br><p><h3>03/04/2025 - Version 2.7: </h3> - Mise a jour de securite.</p></br><p><h3>12/02/2025 - Version 2.6: </h3> - InDev:renomé les schema et table.</p></br><p><h3>04/02/2025 - Version 2.5: </h3> - Correctif bug création de couche.</p></br><p><h3>23/01/2025 - Version 2.4: </h3> - Correctif sur les pkey.</p></br><p><h3>22/01/2025 - Version 2.3: </h3> - Correctif sur la creation de projet.</p></br><p><h3>21/01/2025 - Version 2.2: </h3> - Correctif sur la longeur des nom.</p></br><p><h3>07/01/2025 - Version 2.1: </h3> - ByPass du certif ssl ci erreur.</p></br><p><h3>22/10/2024 - Version 2.0:</h3>- Refont du code.</p>
changelog=<h2>CenRa_POSTGIS:</h2></br><p><h3>21/05/2026 - Version 3.4: </h3> - Optimisation des performances hors connexion.</p></br><p><h3>23/03/2026 - Version 3.3: </h3> - Optimisation pour QGIS.</p></br><p><h3>12/03/2026 - Version 3.2: </h3> - qgisMaximumVersion est 4.0.</p></br><p><h3>30/07/2025 - Version 3.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 3.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>09/04/2025 - Version 2.9: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 2.8: </h3> - Optimisation pour le TT.</p></br><p><h3>03/04/2025 - Version 2.7: </h3> - Mise a jour de securite.</p></br><p><h3>12/02/2025 - Version 2.6: </h3> - InDev:renomé les schema et table.</p></br><p><h3>04/02/2025 - Version 2.5: </h3> - Correctif bug création de couche.</p></br><p><h3>23/01/2025 - Version 2.4: </h3> - Correctif sur les pkey.</p></br><p><h3>22/01/2025 - Version 2.3: </h3> - Correctif sur la creation de projet.</p></br><p><h3>21/01/2025 - Version 2.2: </h3> - Correctif sur la longeur des nom.</p></br><p><h3>07/01/2025 - Version 2.1: </h3> - ByPass du certif ssl ci erreur.</p></br><p><h3>22/10/2024 - Version 2.0:</h3>- Refont du code.</p>
# tags are comma separated with spaces allowed
tags=cenra, postgis, database
+3 -2
View File
@@ -5,7 +5,7 @@ from __future__ import absolute_import
# from builtins import next
# from builtins import str
# from builtins import object
# import qgis
import os
from qgis.PyQt.QtCore import QSettings
from qgis.PyQt.QtWidgets import QDialog, QMessageBox
# from qgis.PyQt.QtGui import QIcon
@@ -18,7 +18,8 @@ from qgis.PyQt import QtGui
from qgis.core import QgsSettings, Qgis
try:
from .tools.PythonSQL import login_base
if os.path.exists('N:'):
from .tools.PythonSQL import login_base
except ValueError:
print('Pas de fichier PythonSQL')
+4 -3
View File
@@ -4,8 +4,8 @@ from __future__ import absolute_import
# Import the PyQt and QGIS libraries
from builtins import next
from builtins import str
# from builtins import object
# import qgis
import os
from qgis.PyQt.QtCore import QSettings
from qgis.PyQt.QtWidgets import QDialog, QMessageBox
# from qgis.PyQt.QtGui import QIcon
@@ -16,7 +16,8 @@ from qgis.PyQt import QtGui
from qgis.core import QgsSettings
try:
from .tools.PythonSQL import login_base
if os.path.exists('N:'):
from .tools.PythonSQL import login_base
except ValueError:
print('Pas de fichier PythonSQL')
# from .tools.SQLRequet import *
+5 -4
View File
@@ -5,7 +5,7 @@ from __future__ import absolute_import
# from builtins import next
from builtins import str
# from builtins import object
# import qgis
import os
from qgis.PyQt.QtCore import QSettings
from qgis.PyQt.QtWidgets import QDialog, QMessageBox, QDialogButtonBox
# from qgis.PyQt.QtGui import QIcon
@@ -18,7 +18,8 @@ from qgis.PyQt import QtGui
from qgis.core import QgsSettings, QgsDataSourceUri, QgsProject
try:
from .tools.PythonSQL import login_base
if os.path.exists('N:'):
from .tools.PythonSQL import login_base
except ValueError:
print('Pas de fichier PythonSQL')
# from .tools.SQLRequet import *
@@ -48,8 +49,8 @@ try:
dbname = account[4]
cur = account[7]
con = account[8]
except ValueError:
print('')
except NameError:
print('Fails to login DB for account')
class Postgis_Rename(QDialog, EDITOR_CLASS):
+3 -3
View File
@@ -156,7 +156,7 @@ def maj_verif(NAME):
# url = qgis.utils.pluginMetadata(NAME, 'repository')
# URL = url+'/raw/branch/main/plugins.xml'
URL = 'https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/plugins.xml'
# print(URL)
# print(URL)
version = qgis.utils.pluginMetadata(NAME, 'version')
len_version = len(version)
try:
@@ -169,10 +169,10 @@ def maj_verif(NAME):
version_web = str(urllib.request.urlopen(URL).read())
plugin_num = version_web.find(NAME)
valeur_version_web = version_web.find('<version>', plugin_num) + 9
version_plugin = version_web[valeur_version_web:valeur_version_web + len_version]
version_plugin = version_web[valeur_version_web: valeur_version_web + len_version]
if version_plugin != version:
iface.messageBar().pushMessage("MAJ :", "Des mise à jour de plugin sont disponibles.", level=Qgis.Info, duration=30)
except urllib.error.URLError:
except NameError:
print("error gitea version ssl")
else:
iface.messageBar().pushMessage("WiFi :", "Pas de connection à internet.", level=Qgis.Warning, duration=30)
+3 -7
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CenRa_Metabase_editorwidget_base</class>
<widget class="QDialog" name="CenRa_Metabase_editorwidget_base">
<widget class="QDialog" name="CenRa_about_base">
<property name="geometry">
<rect>
<x>0</x>
@@ -13,10 +13,6 @@
<property name="windowTitle">
<string>Journal des modifications</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>../../CenRa_Metabase/tools/ui/icon.svg</normaloff>../../CenRa_Metabase/tools/ui/icon.svg</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="scrollArea">
@@ -38,7 +34,7 @@
<x>0</x>
<y>0</y>
<width>453</width>
<height>570</height>
<height>547</height>
</rect>
</property>
<widget class="QGroupBox" name="groupBox">
@@ -70,7 +66,7 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::NoButton</set>
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
+3 -2
View File
@@ -11,9 +11,10 @@
[general]
name=CenRa SICEN
qgisMinimumVersion=3.0
qgisMaximumVersion=4.99
supportsQt6=True
description=Filtre des données saisies dans SICEN et export d'une liste d'espèces.
version=2.1
version=2.2
author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr
@@ -22,7 +23,7 @@ email=si_besoin@cen-rhonealpes.fr
# Optional items:
# Uncomment the following line and add your changelog entries:
changelog=<h2>CenRa_SICEN:</h2></br><p><h3>30/07/2025 - Version 2.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 2.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>09/04/2025 - Version 1.11: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 1.10: </h3> - Optimisation pour le TT.</p></br><p><h3>03/04/2025 - Version 1.9: </h3> - Mise a jour de securite.</p></br><p><h3>07/01/2025 - Version 1.8: </h3> - ByPass du certif ssl ci erreur.</br></p><p><h3>13/09/2024 - Version 1.7:</h3> - Il est maintenant possible de sélectionné plusieurs entité pour le filtre par Emprise.</br>- Ajoute d'un changelog.</br>- Ajoute une vérification de mise à jour.</p>
changelog=<h2>CenRa_SICEN:</h2></br><p><h3>12/03/2026 - Version 2.2: </h3> - qgisMaximumVersion est 4.0.</p></br><p><h3>30/07/2025 - Version 2.1: </h3> - Correctife de bug.</p></br><p><h3>19/05/2025 - Version 2.0: </h3> - Compatible PyQt5 et PyQt6</p></br><p><h3>09/04/2025 - Version 1.11: </h3> - Correctif bug en TT.</p></br><p><h3>09/04/2025 - Version 1.10: </h3> - Optimisation pour le TT.</p></br><p><h3>03/04/2025 - Version 1.9: </h3> - Mise a jour de securite.</p></br><p><h3>07/01/2025 - Version 1.8: </h3> - ByPass du certif ssl ci erreur.</br></p><p><h3>13/09/2024 - Version 1.7:</h3> - Il est maintenant possible de sélectionné plusieurs entité pour le filtre par Emprise.</br>- Ajoute d'un changelog.</br>- Ajoute une vérification de mise à jour.</p>
# tags are comma separated with spaces allowed
tags=cenra, postgis, sicen
+24 -27
View File
@@ -11,7 +11,7 @@ from qgis.PyQt.QtWidgets import QMenu, QAction, QFileDialog
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, qVersion
# Initialize Qt resources from file resources.py
from . import resources_rc
# from . import resources_rc
# Import the code for the dialog
from .sicendialog import SICENDialog
@@ -22,21 +22,16 @@ import csv
from .forms.about_form import AboutDialog
# import psycopg2
# import psycopg2.extras
# import base64
import socket
import os
from .tools.resources import maj_verif, pyperclip
from .tools.resources import maj_verif, pyperclip, resources_path
pyperclip()
try:
from .tools.PythonSQL import login_base
except ValueError:
print('Pas de fichier PythonSQL')
# import sys
class SICEN(object):
@@ -73,43 +68,43 @@ class SICEN(object):
self.toolBar.setObjectName("SICEN")
# Create action that will start plugin configuration
self.action = QAction(
QIcon(":/plugins/sicen/sicen.png"),
self.action_open = QAction(
QIcon(resources_path("icon", "sicen.png")),
u"Ouverture des données SICEN", self.iface.mainWindow())
self.action.setEnabled(False)
self.action_open.setEnabled(False)
if os.access('N:/', os.R_OK):
self.action.setEnabled(True)
self.action_open.setEnabled(True)
# connect the action to the run method
self.action.triggered.connect(self.ouverture)
self.action_open.triggered.connect(self.ouverture)
# Add toolbar button and menu item
self.toolBar.addAction(self.action)
self.iface.addPluginToMenu(u"SICEN", self.action)
self.toolBar.addAction(self.action_open)
self.iface.addPluginToMenu(u"SICEN", self.action_open)
# Create action that will start plugin configuration
self.action = QAction(
QIcon(":/plugins/sicen/sicen_export.png"),
self.action_export = QAction(
QIcon(resources_path("icon", "sicen_export.png")),
u"Export liste d'espèces", self.iface.mainWindow())
self.action.setEnabled(False)
self.action_export.setEnabled(False)
IPAddr = socket.gethostbyname(socket.gethostname())
if IPAddr[0:11] == "100.100.100":
self.action.setEnabled(True)
self.action_export.setEnabled(True)
elif IPAddr[0:9] == "192.168.0":
self.action.setEnabled(True)
self.action_export.setEnabled(True)
elif IPAddr[0:9] == "192.168.1":
self.action.setEnabled(True)
self.action_export.setEnabled(True)
# connect the action to the run method
self.action.triggered.connect(self.export)
self.action_export.triggered.connect(self.export)
# Add toolbar button and menu item
self.toolBar.addAction(self.action)
self.iface.addPluginToMenu(u"SICEN", self.action)
self.toolBar.addAction(self.action_export)
self.iface.addPluginToMenu(u"SICEN", self.action_export)
self.menu = QMenu()
self.menu.setTitle(QCoreApplication.translate("SICEN", "&SICEN"))
self.sicen_ouverture = QAction(QIcon(":/plugins/SICEN/sicen.png"), QCoreApplication.translate("SICEN", u"Ouverture des données SICEN"), self.iface.mainWindow())
self.sicen_export = QAction(QIcon(":/plugins/SICEN/sicen_export.png"), QCoreApplication.translate("SICEN", u"Export liste d'espèces"), self.iface.mainWindow())
self.sicen_ouverture = QAction(QIcon(resources_path("icon", "sicen.png")), QCoreApplication.translate("SICEN", u"Ouverture des données SICEN"), self.iface.mainWindow())
self.sicen_export = QAction(QIcon(resources_path("icon", "sicen_export.png")), QCoreApplication.translate("SICEN", u"Export liste d'espèces"), self.iface.mainWindow())
self.menu.addActions([self.sicen_ouverture, self.sicen_export])
@@ -127,8 +122,10 @@ class SICEN(object):
def unload(self):
# Remove the plugin menu item and icon
self.iface.removePluginMenu(u"&SICEN", self.action)
self.iface.removeToolBarIcon(self.action)
self.iface.removePluginMenu(u"&SICEN", self.action_open)
self.iface.removeToolBarIcon(self.action_open)
self.iface.removePluginMenu(u"&SICEN", self.action_export)
self.iface.removeToolBarIcon(self.action_export)
# run method that performs all the real work
def ouverture(self):

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

+1 -1
View File
@@ -90,7 +90,7 @@ def resources_path(*args):
:return: Absolute path to the resources folder.
:rtype: str
"""
path = abspath(abspath(join(plugin_path(), "CenRa_COPIE\\tools")))
path = abspath(abspath(join(plugin_path(), "CenRa_SICEN\\tools")))
for item in args:
path = abspath(join(path, item))
return path
+34 -25
View File
@@ -1,25 +1,27 @@
<plugins>
<pyqgis_plugin name="CenRa_POSTGIS" version="3.1">
<pyqgis_plugin name="CenRa_POSTGIS" version="3.4">
<description>Depot pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.</description>
<version>3.1</version>
<version>3.4</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<qgis_maximum_version>4.99</qgis_maximum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_POSTGIS.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
<author_name>CEN-Rhone-Alpes</author_name>
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_POSTGIS.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-02-06</create_date>
<update_date>2025-07-30</update_date>
<create_date>2026-05-21</create_date>
<update_date>2026-03-12</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,postgis</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_COPIE" version="3.1">
<pyqgis_plugin name="CenRa_COPIE" version="3.2">
<description>Depot pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.</description>
<version>3.1</version>
<version>3.2</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<qgis_maximum_version>4.99</qgis_maximum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_COPIE.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
@@ -27,16 +29,17 @@
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_COPIE.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-02-06</create_date>
<update_date>2025-07-30</update_date>
<update_date>2026-03-12</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,copie</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_SICEN" version="2.1">
<pyqgis_plugin name="CenRa_SICEN" version="2.2">
<description>Depot pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.</description>
<version>2.1</version>
<version>2.2</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<qgis_maximum_version>4.99</qgis_maximum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_SICEN.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
@@ -44,33 +47,35 @@
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_SICEN.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-02-06</create_date>
<update_date>2025-07-30</update_date>
<update_date>2026-03-12</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,sicen</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_FLUX" version="3.15">
<pyqgis_plugin name="CenRa_FLUX" version="3.23">
<description>Depot pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.</description>
<version>3.15</version>
<version>3.23</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<qgis_maximum_version>4.99</qgis_maximum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_FLUX.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
<author_name>CEN-Rhone-Alpes</author_name>
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_FLUX.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-02-06</create_date>
<update_date>2025-12-15</update_date>
<create_date>2026-05-21</create_date>
<update_date>2026-03-12</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,flux</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_METABASE" version="0.3.1">
<pyqgis_plugin name="CenRa_METABASE" version="0.3.2">
<description>Depot pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.</description>
<version>0.3.1</version>
<version>0.3.2</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<qgis_maximum_version>4.99</qgis_maximum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_METABASE.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
@@ -78,41 +83,43 @@
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_METABASE.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-09-12</create_date>
<update_date>2025-07-30</update_date>
<update_date>2026-03-12</update_date>
<experimental>True</experimental>
<deprecated>False</deprecated>
<tags>cenra,metabase</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_AUTOMAP" version="2.7">
<pyqgis_plugin name="CenRa_AUTOMAP" version="2.11">
<description>Depot pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.</description>
<version>2.7</version>
<version>2.11</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<qgis_maximum_version>4.99</qgis_maximum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_AUTOMAP.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
<author_name>CEN-Rhone-Alpes</author_name>
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_AUTOMAP.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-09-25</create_date>
<update_date>2025-12-18</update_date>
<create_date>2026-05-21</create_date>
<update_date>2026-03-12</update_date>
<experimental>False</experimental>
<deprecated>False</deprecated>
<tags>cenra,mise en page,atlas</tags>
</pyqgis_plugin>
<pyqgis_plugin name="CenRa_PAGERENDER" version="0.2.3">
<pyqgis_plugin name="CenRa_PAGERENDER" version="0.2.5">
<description>Depot pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.</description>
<version>0.2.3</version>
<version>0.2.5</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<qgis_maximum_version>4.99</qgis_maximum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_PAGERENDER.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
<author_name>CEN-Rhone-Alpes</author_name>
<download_url>https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_PAGERENDER.zip</download_url>
<uploaded_by>CEN-Rhone-Alpes</uploaded_by>
<create_date>2024-10-09</create_date>
<update_date>2025-12-15</update_date>
<create_date>2026-03-23</create_date>
<update_date>2026-03-12</update_date>
<experimental>True</experimental>
<deprecated>False</deprecated>
<tags>cenra,mise en page,atlas</tags>
@@ -122,6 +129,7 @@
<description>Depot pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.</description>
<version>0.1.0</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<qgis_maximum_version>4.99</qgis_maximum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>CenRa_gn2qgis.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>
@@ -139,6 +147,7 @@
<description>Depot pour les extensiont QGIS du CEN Rhone-Alpes, sur GitHub.</description>
<version>0.1.0</version>
<qgis_minimum_version>3.16</qgis_minimum_version>
<qgis_maximum_version>4.99</qgis_maximum_version>
<homepage>https://plateformesig.cenra-outils.org/</homepage>
<file_name>BiodivAURA.zip</file_name>
<icon>CEN-Rhone-Alpes.png</icon>