diff --git a/CenRa_POSTGIS/CenRa_Postgis.py b/CenRa_POSTGIS/CenRa_Postgis.py index d87cf1ab..7636fc5f 100644 --- a/CenRa_POSTGIS/CenRa_Postgis.py +++ b/CenRa_POSTGIS/CenRa_Postgis.py @@ -21,6 +21,7 @@ from .tools.resources import ( ) from .postgis_editor import Postgis_Editor from .postgis_creator import Postgis_Creator +from .postgis_rename import Postgis_Rename from .about_form import AboutDialog from PyQt5.QtCore import * @@ -30,6 +31,7 @@ class PgPostgis: """ Constructor. """ self.action_editor = None self.action_creator = None + self.action_rename = None # self.issues = None self.provider = None self.locator_filter = None @@ -58,6 +60,7 @@ class PgPostgis: icon = QIcon(resources_path('icons', 'page_new.png')) icon2 = QIcon(resources_path('icons', 'page_ajout.png')) + icon3 = QIcon(resources_path('icons', 'page_rename.png')) # Open the online help self.help_action = QAction(icon, "CenRa_Postgis", iface.mainWindow()) @@ -75,6 +78,21 @@ class PgPostgis: self.postgis_editor = QAction(icon2, 'dossier_editor',None) self.toolBar.addAction(self.postgis_editor) self.postgis_editor.triggered.connect(self.open_editor) + if not self.action_rename: + self.action_rename = Postgis_Rename() + + self.postgis_rename = QAction(icon3, 'dossier_rename',None) + self.toolBar.addAction(self.postgis_rename) + self.postgis_rename.triggered.connect(self.open_rename) + + 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) + self.postgis_rename.setVisible(1) + else: + self.action_rename.setEnabled(False) + self.postgis_rename.setEnabled(False) + self.postgis_rename.setVisible(0) def open_about_dialog(self): """ @@ -94,12 +112,18 @@ class PgPostgis: self.action_creator.show() self.action_creator.raise_() + def open_rename(self): + self.action_rename.show() + self.action_rename.raise_() + def unload(self): """ Unload the plugin. """ if self.action_editor: iface.removePluginMenu('CenRa_Postgis',self.postgis_editor) if self.action_creator: iface.removePluginMenu('CenRa_Postgis',self.postgis_creator) + if self.action_rename: + iface.removePluginMenu('CenRa_Postgis',self.postgis_rename) if self.provider: QgsApplication.processingRegistry().removeProvider(self.provider) diff --git a/CenRa_POSTGIS/metadata.txt b/CenRa_POSTGIS/metadata.txt index 48fffbf1..05aad1ce 100644 --- a/CenRa_POSTGIS/metadata.txt +++ b/CenRa_POSTGIS/metadata.txt @@ -12,7 +12,7 @@ name=CenRa_POSTGIS qgisMinimumVersion=3.0 description=Permet de crée un dossier dans la base PostGis -version=2.5 +version=2.6 author=Conservatoire d'Espaces Naturels de Rhône-Alpes email=si_besoin@cen-rhonealpes.fr @@ -21,7 +21,7 @@ email=si_besoin@cen-rhonealpes.fr # Optional items: # Uncomment the following line and add your changelog entries: -changelog=

CenRa_POSTGIS:


04/02/2025 - Version 2.5:

- Correctif bug création de couche.


23/01/2025 - Version 2.4:

- Correctif sur les pkey.


22/01/2025 - Version 2.3:

- Correctif sur la creation de projet.


21/01/2025 - Version 2.2:

- Correctif sur la longeur des nom.


07/01/2025 - Version 2.1:

- ByPass du certif ssl ci erreur.


22/10/2024 - Version 2.0:

- Refont du code.

+changelog=

CenRa_POSTGIS:


12/02/2025 - Version 2.6:

- InDev:renomé les schema et table.


04/02/2025 - Version 2.5:

- Correctif bug création de couche.


23/01/2025 - Version 2.4:

- Correctif sur les pkey.


22/01/2025 - Version 2.3:

- Correctif sur la creation de projet.


21/01/2025 - Version 2.2:

- Correctif sur la longeur des nom.


07/01/2025 - Version 2.1:

- ByPass du certif ssl ci erreur.


22/10/2024 - Version 2.0:

- Refont du code.

# tags are comma separated with spaces allowed tags=cenra, postgis, database diff --git a/CenRa_POSTGIS/postgis_creator.py b/CenRa_POSTGIS/postgis_creator.py index 90ce8d9a..a1928568 100644 --- a/CenRa_POSTGIS/postgis_creator.py +++ b/CenRa_POSTGIS/postgis_creator.py @@ -50,6 +50,7 @@ class Postgis_Creator(QDialog, EDITOR_CLASS): # run method that performs all the real work def raise_(self): + self.activateWindow() # show the dialog self.show() # Run the dialog event loop diff --git a/CenRa_POSTGIS/postgis_editor.py b/CenRa_POSTGIS/postgis_editor.py index 9f238a19..0d591f31 100644 --- a/CenRa_POSTGIS/postgis_editor.py +++ b/CenRa_POSTGIS/postgis_editor.py @@ -50,6 +50,7 @@ class Postgis_Editor(QDialog, EDITOR_CLASS): ### Outil Ajout de nouvelles couche a un dossier def raise_(self): + self.activateWindow() first_conn = psycopg2.connect("host=" + host + " port=" + port + " dbname="+dbname+" user=first_cnx password=" + password) first_cur = first_conn.cursor(cursor_factory = psycopg2.extras.DictCursor) first_cur.execute("SELECT mdp_w, login_w FROM pg_catalog.pg_user t1, admin_sig.vm_users_sig t2 WHERE t2.oid = t1.usesysid AND (login_w = '" + os_user + "' OR login_w = '" + os_user + "')") diff --git a/CenRa_POSTGIS/postgis_rename.py b/CenRa_POSTGIS/postgis_rename.py new file mode 100644 index 00000000..0c03164f --- /dev/null +++ b/CenRa_POSTGIS/postgis_rename.py @@ -0,0 +1,187 @@ +# -*- coding: utf-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 +from qgis.PyQt.QtCore import QSettings +from qgis.PyQt.QtWidgets import QAction, QMenu, QDialog, QMessageBox +from qgis.PyQt.QtGui import QIcon +from PyQt5.QtCore import * +from PyQt5.QtGui import * +from PyQt5 import QtGui +from qgis.core import * +from qgis.core import QgsDataSourceUri + +from .tools.PythonSQL import * +from .tools.resources import ( + load_ui, + resources_path, + login_base, + send_issues, + create_vierge, + create_contour, + create_travaux, + create_habita +) +from .issues import CenRa_Issues + +import os.path +import webbrowser, os +import psycopg2 +import psycopg2.extras +import base64 +from qgis.utils import iface + +EDITOR_CLASS = load_ui('CenRa_PostgisRename_base.ui') + +first_conn = psycopg2.connect("host=" + host + " port=" + port + " dbname="+dbname+" user=first_cnx password=" + password) +first_cur = first_conn.cursor(cursor_factory = psycopg2.extras.DictCursor) +first_cur.execute("SELECT mdp_w, login_w FROM pg_catalog.pg_user t1, admin_sig.vm_users_sig t2 WHERE t2.oid = t1.usesysid AND (login_w = '" + os_user + "' OR login_w = '" + os_user + "')") +res_ident = first_cur.fetchone() +mdp = base64.b64decode(str(res_ident[0])).decode('utf-8') +user = res_ident[1] + +con = psycopg2.connect("host=" + host + " port=" + port + " dbname="+dbname+" user=" + user + " password=" + mdp) +cur = con.cursor(cursor_factory = psycopg2.extras.DictCursor) +first_conn.close() + +class Postgis_Rename(QDialog, EDITOR_CLASS): + + def __init__(self, parent=None): + _ = parent + super().__init__() + self.setupUi(self) + self.settings = QgsSettings() + self.s = QSettings() + self.setWindowIcon(QtGui.QIcon(resources_path('icons','icon.png'))) + self.iface = iface + + self.schema.currentIndexChanged.connect(self.Test) + self.buttonBox.accepted.connect(self.msgBox) + ### Outil Ajout de nouvelles couche a un dossier + def raise_(self): + self.activateWindow() + self.groupBox_2.hide() + GET_ALL_SCHEMA = """SELECT DISTINCT table_schema FROM information_schema.tables WHERE table_schema LIKE '_form_%' OR table_schema LIKE '_01_%' OR table_schema LIKE '_07_%' OR table_schema LIKE '_26_%' OR table_schema LIKE '_42_%' OR table_schema LIKE '_69_%' ORDER BY table_schema;""" + cur.execute(GET_ALL_SCHEMA) + AllSchema = cur.fetchall() + last_value_schema = self.schema.currentText() + last_value_departement = self.departement.currentText() + self.schema.clear() + self.departement.clear() + self.schema.addItems(['']) + for Schema in AllSchema: + self.schema.addItems(Schema) + self.departement.addItems(['','01','07','26','42','69','form']) + if last_value_schema != '': + self.schema.setCurrentIndex(self.schema.findText(last_value_schema)) + if last_value_departement != '': + self.departement.setCurrentIndex(self.departement.findText(last_value_departement)) + + def Test(self): + if self.schema.currentText() != '': + self.loadValue() + else: + self.old_name.setText('') + + def loadValue(self): + oldSchema = self.schema.currentText() + if oldSchema[:6] == '_form_': + oldSchema = self.schema.currentText()[6:] + prefixSchema = self.schema.currentText()[1:5] + else: + oldSchema = self.schema.currentText()[4:] + prefixSchema = self.schema.currentText()[1:3] + if oldSchema[:3] == 'at_': + oldSchema = oldSchema[3:] + self.animation.setChecked(1) + else: + self.animation.setChecked(0) + self.old_name.setText(oldSchema) + self.departement.setCurrentIndex(self.departement.findText(prefixSchema)) + + def updateName(self): + if self.departement.currentText() != '': + oldTableName = self.old_name.text() + newTableName = ((self.new_name.text()).lower()).replace(' ','_') + newPrefixSchema = '_'+self.departement.currentText()+'_' + if self.schema.currentText()[:6] == '_form_': + oldPrefixSchema = self.schema.currentText()[:6] + if (self.schema.currentText()[6:9]) == "at_": + oldPrefixSchema=oldPrefixSchema+'at_' + else: + oldPrefixSchema = self.schema.currentText()[:4] + if (self.schema.currentText()[4:7]) == 'at_': + oldPrefixSchema=oldPrefixSchema+'at_' + + if self.animation.isChecked(): + newPrefixSchema=newPrefixSchema+'at_' + oldSchemaName = oldPrefixSchema+oldTableName + newSchemaName = newPrefixSchema+newTableName + + if oldSchemaName != newSchemaName: + global AllSQLrun + allSQLrun='' + + SQL_UPDATE = """UPDATE public.layer_styles SET f_table_schema = '"""+newSchemaName+"""',f_table_name = replace(replace(f_table_name,'"""+oldTableName+"""','"""+newTableName+"""'),'"""+oldPrefixSchema+"""','"""+newPrefixSchema+"""') WHERE f_table_schema LIKE '"""+oldSchemaName+"""';""" + allSQLrun = allSQLrun+SQL_UPDATE + cur.execute(SQL_UPDATE) + + SQL_GET_TABLE_RENAME = """SELECT table_name,replace(replace(table_name,'"""+oldTableName+"""','"""+newTableName+"""'),'"""+oldPrefixSchema+"""','"""+newPrefixSchema+"""') from information_schema.tables WHERE table_schema LIKE '"""+oldSchemaName+"""';""" + cur.execute(SQL_GET_TABLE_RENAME) + allTableRename = cur.fetchall() + allTableList = [] + for TableRename in allTableRename: + oldTable = TableRename[0] + newTable = TableRename[1] + allTableList.append([oldTable,newSchemaName,newTable]) + SQL_RENAME_TABLE = """ALTER TABLE """+oldSchemaName+'.'+oldTable+""" RENAME TO """+newTable+""";""" + allSQLrun = allSQLrun+SQL_RENAME_TABLE + cur.execute(SQL_RENAME_TABLE) + + SQL_RENAME_SCHEMA = 'ALTER SCHEMA '+oldSchemaName+' RENAME TO '+newSchemaName + allSQLrun = allSQLrun+SQL_RENAME_SCHEMA + cur.execute(SQL_RENAME_SCHEMA) + #print(allSQLrun) + con.commit() + for LayerOpen in allTableList: + self.UnloadLoadLayers(LayerOpen[0],LayerOpen[1],LayerOpen[2]) + + + def UnloadLoadLayers(self,OldName,NewSchema,NewTable): + allLayers = (QgsProject.instance().mapLayers().values()) + listLayers = [] + listLayersName = [] + for layer in allLayers: + listLayers.append(layer) + listLayersName.append(layer.name()) + if OldName in listLayersName: + layer = (listLayers[listLayersName.index(OldName)]) + provider = layer.dataProvider() + dbname = (QgsDataSourceUri(provider.dataSourceUri()).database()) + user = QgsDataSourceUri(provider.dataSourceUri()).username() + mdp = QgsDataSourceUri(provider.dataSourceUri()).password() + host = QgsDataSourceUri(provider.dataSourceUri()).host() + port = QgsDataSourceUri(provider.dataSourceUri()).port() + + ### Affichage de la table + uri = QgsDataSourceUri() + # set host name, port, database name, username and password + uri.setConnection(host ,port ,dbname ,user ,mdp) + # set database schema, table name, geometry column and optionaly subset (WHERE clause) + uri.setDataSource(NewSchema, NewTable, 'geom') + QgsProject.instance().removeMapLayer(layer.id()) + layer = self.iface.addVectorLayer(uri.uri(), NewTable, "postgres") + + def msgBox(self): + self.QMBquestion = QMessageBox() + self.QMBquestion.setWindowTitle(u"Attention !") + self.QMBquestion.setIcon(QMessageBox.Warning) + self.QMBquestion.setText("Attention, le renommage de dossier PostGIS peut engendrer des pertes de liaisons avec des projets QGIS !") + self.QMBquestion.setStandardButtons(QMessageBox.Yes|QMessageBox.No) + self.QMBquestion = self.QMBquestion.exec() + if self.QMBquestion == QMessageBox.Yes: + self.updateName() diff --git a/CenRa_POSTGIS/tools/icons/page_rename.png b/CenRa_POSTGIS/tools/icons/page_rename.png new file mode 100644 index 00000000..a9c00199 Binary files /dev/null and b/CenRa_POSTGIS/tools/icons/page_rename.png differ diff --git a/CenRa_POSTGIS/tools/ui/CenRa_PostgisRename_base.ui b/CenRa_POSTGIS/tools/ui/CenRa_PostgisRename_base.ui new file mode 100644 index 00000000..2299e68b --- /dev/null +++ b/CenRa_POSTGIS/tools/ui/CenRa_PostgisRename_base.ui @@ -0,0 +1,314 @@ + + + table_postgis + + + + 0 + 0 + 533 + 364 + + + + Ajout d'une table + + + + + 360 + 330 + 161 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 170 + 0 + 171 + 31 + + + + + 14 + 75 + true + + + + Création de table + + + + + + 10 + 80 + 511 + 101 + + + + + 75 + true + + + + Tester mon eligibilite : + + + Qt::AlignCenter + + + + + 10 + 19 + 491 + 71 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Compte + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Couche + + + + + + + + + + 10 + 40 + 511 + 31 + + + + + + + + 90 + 16777215 + + + + Code analytique : + + + + + + + + + + + + 10 + 180 + 511 + 151 + + + + + 75 + true + + + + Les changement : + + + Qt::AlignCenter + + + + + 10 + 20 + 491 + 61 + + + + + + + + 50 + false + + + + Nouvau nom : + + + + + + + + 50 + false + + + + Partie renome : + + + + + + + false + + + + 75 + true + true + + + + + + + + + + + + + 10 + 80 + 491 + 61 + + + + + + + + 130 + 16777215 + + + + + 50 + false + + + + Département/Animation : + + + + + + + Animation territoriale + + + + + + + + + + + + + + buttonBox + accepted() + table_postgis + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + table_postgis + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/plugins.xml b/plugins.xml index 06f08add..0f69c8e8 100644 --- a/plugins.xml +++ b/plugins.xml @@ -1,8 +1,8 @@ - + - 2.5 + 2.6 3.16 https://plateformesig.cenra-outils.org/ CenRa_POSTGIS.zip @@ -11,7 +11,7 @@ https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/CenRa_POSTGIS.zip CEN-Rhone-Alpes 2024-02-06 - 2025-02-04 + 2025-02-12 False False cenra,postgis