Téléverser les fichiers vers "CenRa_Metabase"

This commit is contained in:
Tom LAVEILLE 2024-10-08 12:15:09 +02:00
parent 839eb525e4
commit f831f2e5a3
2 changed files with 490 additions and 483 deletions

View File

@ -1,481 +1,488 @@
"""Dock file.""" """Dock file."""
__copyright__ = 'Copyright 2020, 3Liz' __copyright__ = 'Copyright 2020, 3Liz'
__license__ = 'GPL version 3' __license__ = 'GPL version 3'
__email__ = 'info@3liz.org' __email__ = 'info@3liz.org'
import logging import logging
import os import os
from collections import namedtuple from collections import namedtuple
from enum import Enum from enum import Enum
from functools import partial from functools import partial
from pathlib import Path from pathlib import Path
from xml.dom.minidom import parseString from xml.dom.minidom import parseString
from qgis.core import ( from qgis.core import (
NULL, NULL,
QgsApplication, QgsApplication,
QgsDataSourceUri, QgsDataSourceUri,
QgsProject, QgsProject,
QgsProviderConnectionException, QgsProviderConnectionException,
QgsProviderRegistry, QgsProviderRegistry,
QgsRasterLayer, QgsRasterLayer,
QgsSettings, QgsSettings,
QgsVectorLayer, QgsVectorLayer,
) )
from qgis.PyQt.QtCore import QLocale, QUrl from qgis.PyQt.QtCore import QLocale, QUrl
from qgis.PyQt.QtGui import QDesktopServices, QIcon from qgis.PyQt.QtGui import QDesktopServices, QIcon
from qgis.PyQt.QtPrintSupport import QPrinter from qgis.PyQt.QtPrintSupport import QPrinter
from qgis.PyQt.QtWebKitWidgets import QWebPage from qgis.PyQt.QtWebKitWidgets import QWebPage
from qgis.PyQt.QtWidgets import ( from qgis.PyQt.QtWidgets import (
QDialog, QDialog,
QAction, QAction,
QDockWidget, QDockWidget,
QFileDialog, QFileDialog,
QInputDialog, QInputDialog,
QMenu, QMenu,
QToolButton, QToolButton,
) )
from qgis.gui import * from qgis.gui import *
from qgis.utils import iface from qgis.utils import iface
''' '''
from pg_metadata.connection_manager import ( from pg_metadata.connection_manager import (
check_pgmetadata_is_installed, check_pgmetadata_is_installed,
connections_list, connections_list,
settings_connections_names, settings_connections_names,
) )
''' '''
from CenRa_Metabase.resources.i18n import tr
from .tools.resources import (
from CenRa_Metabase.resources.resources import ( load_ui,
load_ui, resources_path,
resources_path, login_base,
login_base, )
)
DOCK_CLASS = load_ui('CenRa_Metabase_dockwidget_base.ui')
DOCK_CLASS = load_ui('CenRa_Metabase_dockwidget_base.ui') LOGGER = logging.getLogger('CenRa_Metabase')
LOGGER = logging.getLogger('CenRa_Metabase')
class Format(namedtuple('Format', ['label', 'ext'])):
class Format(namedtuple('Format', ['label', 'ext'])): """ Format available for exporting metadata. """
""" Format available for exporting metadata. """ pass
pass
class OutputFormats(Format, Enum):
class OutputFormats(Format, Enum): """ Output format for a metadata sheet. """
""" Output format for a metadata sheet. """ PDF = Format(label='PDF', ext='pdf')
PDF = Format(label='PDF', ext='pdf') HTML = Format(label='HTML', ext='html')
HTML = Format(label='HTML', ext='html') DCAT = Format(label='DCAT', ext='xml')
DCAT = Format(label='DCAT', ext='xml')
class CenRa_Metabase(QDockWidget, DOCK_CLASS):
class CenRa_Metabase(QDockWidget, DOCK_CLASS):
def __init__(self, parent=None):
def __init__(self, parent=None): _ = parent
_ = parent super().__init__()
super().__init__() self.setupUi(self)
self.setupUi(self) self.settings = QgsSettings()
self.settings = QgsSettings()
self.current_datasource_uri = None
self.current_datasource_uri = None self.current_connection = None
self.current_connection = None
self.viewer.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
self.viewer.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) self.viewer.page().linkClicked.connect(self.open_link)
self.viewer.page().linkClicked.connect(self.open_link)
# Help button
# Help button self.external_help.setText('')
self.external_help.setText('') self.external_help.setIcon(QIcon(QgsApplication.iconPath('mActionHelpContents.svg')))
self.external_help.setIcon(QIcon(QgsApplication.iconPath('mActionHelpContents.svg'))) self.external_help.clicked.connect(self.open_external_help)
self.external_help.clicked.connect(self.open_external_help)
# Flat table button
# Flat table button self.flatten_dataset_table.setText('')
self.flatten_dataset_table.setText('') #self.flatten_dataset_table.setToolTip(tr("Add the catalog table"))
self.flatten_dataset_table.setToolTip(tr("Add the catalog table")) self.flatten_dataset_table.setIcon(QgsApplication.getThemeIcon("/mActionAddHtml.svg"))
self.flatten_dataset_table.setIcon(QgsApplication.getThemeIcon("/mActionAddHtml.svg")) #self.flatten_dataset_table.clicked.connect(self.add_flatten_dataset_table)
#self.flatten_dataset_table.clicked.connect(self.add_flatten_dataset_table)
# Settings menu
# Settings menu self.config.setAutoRaise(True)
self.config.setAutoRaise(True) #self.config.setToolTip(tr("Settings"))
self.config.setToolTip(tr("Settings")) self.config.setPopupMode(QToolButton.InstantPopup)
self.config.setPopupMode(QToolButton.InstantPopup) self.config.setIcon(QgsApplication.getThemeIcon("/mActionOptions.svg"))
self.config.setIcon(QgsApplication.getThemeIcon("/mActionOptions.svg"))
self.auto_open_dock_action = QAction(
self.auto_open_dock_action = QAction( ("Dommage, cette option n'existe pas encore."),
tr('Auto open dock from locator'), iface.mainWindow())
iface.mainWindow()) self.auto_open_dock_action.setCheckable(True)
self.auto_open_dock_action.setCheckable(True) self.auto_open_dock_action.setChecked(
self.auto_open_dock_action.setChecked( self.settings.value("pgmetadata/auto_open_dock", True, type=bool)
self.settings.value("pgmetadata/auto_open_dock", True, type=bool) )
) self.auto_open_dock_action.triggered.connect(self.save_auto_open_dock)
self.auto_open_dock_action.triggered.connect(self.save_auto_open_dock) menu = QMenu()
menu = QMenu() menu.addAction(self.auto_open_dock_action)
menu.addAction(self.auto_open_dock_action) self.config.setMenu(menu)
self.config.setMenu(menu)
# Setting PDF/HTML menu
# Setting PDF/HTML menu self.save_button.setAutoRaise(True)
self.save_button.setAutoRaise(True) #self.save_button.setToolTip(tr("Save metadata"))
self.save_button.setToolTip(tr("Save metadata")) self.save_button.setPopupMode(QToolButton.InstantPopup)
self.save_button.setPopupMode(QToolButton.InstantPopup) self.save_button.setIcon(QIcon(QgsApplication.iconPath('mActionFileSave.svg')))
self.save_button.setIcon(QIcon(QgsApplication.iconPath('mActionFileSave.svg')))
self.save_as_pdf = QAction(
self.save_as_pdf = QAction( ('Enregistrer en PDF') + '',
tr('Enregistrer en PDF') + '', iface.mainWindow())
iface.mainWindow()) self.save_as_pdf.triggered.connect(partial(self.export_dock_content, OutputFormats.PDF))
self.save_as_pdf.triggered.connect(partial(self.export_dock_content, OutputFormats.PDF))
self.save_as_html = QAction(
self.save_as_html = QAction( ('Enregistrer en HTML') + '',
tr('Enregistrer en HTML') + '', iface.mainWindow())
iface.mainWindow()) self.save_as_html.triggered.connect(partial(self.export_dock_content, OutputFormats.HTML))
self.save_as_html.triggered.connect(partial(self.export_dock_content, OutputFormats.HTML)) self.save_as_dcat = QAction(
self.save_as_dcat = QAction( ('Enregistrer en DCAT') + '',
tr('Enregistrer en DCAT') + '', iface.mainWindow())
iface.mainWindow()) self.save_as_dcat.triggered.connect(partial(self.export_dock_content, OutputFormats.DCAT))
self.save_as_dcat.triggered.connect(partial(self.export_dock_content, OutputFormats.DCAT))
self.menu_save = QMenu()
self.menu_save = QMenu() self.menu_save.addAction(self.save_as_pdf)
self.menu_save.addAction(self.save_as_pdf) self.menu_save.addAction(self.save_as_html)
self.menu_save.addAction(self.save_as_html) self.menu_save.addAction(self.save_as_dcat)
self.menu_save.addAction(self.save_as_dcat) self.save_button.setMenu(self.menu_save)
self.save_button.setMenu(self.menu_save) self.save_button.setEnabled(False)
self.save_button.setEnabled(False)
self.metadata = QgsProviderRegistry.instance().providerMetadata('postgres')
self.metadata = QgsProviderRegistry.instance().providerMetadata('postgres')
# Display message in the dock
# Display message in the dock #if not settings_connections_names():
#if not settings_connections_names(): #self.default_html_content_not_installed()
#self.default_html_content_not_installed() #else:
#else: self.default_html_content_not_pg_layer()
self.default_html_content_not_pg_layer()
iface.layerTreeView().currentLayerChanged.connect(self.layer_changed)
iface.layerTreeView().currentLayerChanged.connect(self.layer_changed)
if iface.activeLayer():
if iface.activeLayer(): layer=iface.activeLayer()
layer=iface.activeLayer() iface.layerTreeView().setCurrentLayer(None)
iface.layerTreeView().setCurrentLayer(None) iface.layerTreeView().setCurrentLayer(layer)
iface.layerTreeView().setCurrentLayer(layer)
def export_dock_content(self, output_format: OutputFormats):
def export_dock_content(self, output_format: OutputFormats): """ Export the current displayed metadata sheet to the given format. """
""" Export the current displayed metadata sheet to the given format. """ layer_name = iface.activeLayer().name()
layer_name = iface.activeLayer().name()
file_path = os.path.join(
file_path = os.path.join( os.environ['USERPROFILE'],
self.settings.value("UI/lastFileNameWidgetDir"), 'Desktop\\{name}.{ext}'.format(name=layer_name, ext=output_format.ext)
'{name}.{ext}'.format(name=layer_name, ext=output_format.ext) )
) output_file = QFileDialog.getSaveFileName(
output_file = QFileDialog.getSaveFileName( self,
self, ("Enregistrer en {format}").format(format=output_format.label),
tr("Enregistrer en {format}").format(format=output_format.label), file_path,
file_path, "{label} (*.{ext})".format(
"{label} (*.{ext})".format( label=output_format.label,
label=output_format.label, ext=output_format.ext,
ext=output_format.ext, )
) )
) if output_file[0] == '':
if output_file[0] == '': return
return
self.settings.setValue("UI/lastFileNameWidgetDir", os.path.dirname(output_file[0]))
self.settings.setValue("UI/lastFileNameWidgetDir", os.path.dirname(output_file[0]))
output_file_path = output_file[0]
output_file_path = output_file[0] parent_folder = str(Path(output_file_path).parent)
parent_folder = str(Path(output_file_path).parent)
if output_format == OutputFormats.PDF:
if output_format == OutputFormats.PDF: printer = QPrinter()
printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFormat(QPrinter.PdfFormat) printer.setPageMargins(20, 20, 20, 20, QPrinter.Millimeter)
printer.setPageMargins(20, 20, 20, 20, QPrinter.Millimeter) printer.setOutputFileName(output_file_path)
printer.setOutputFileName(output_file_path) self.viewer.print(printer)
self.viewer.print(printer) iface.messageBar().pushSuccess(
iface.messageBar().pushSuccess( ("Export PDF"),
tr("Export PDF"), (
tr( "The metadata has been exported as PDF successfully in "
"The metadata has been exported as PDF successfully in " "<a href=\"{}\">{}</a>").format(parent_folder, output_file_path)
"<a href=\"{}\">{}</a>").format(parent_folder, output_file_path) )
)
elif output_format in [OutputFormats.HTML,OutputFormats.DCAT]:
elif output_format in [OutputFormats.HTML,OutputFormats.DCAT]: if output_format == OutputFormats.HTML:
if output_format == OutputFormats.HTML: data_str = self.viewer.page().currentFrame().toHtml()
data_str = self.viewer.page().currentFrame().toHtml() else:
else: layer = iface.activeLayer()
layer = iface.activeLayer() uri = layer.dataProvider().uri()
uri = layer.dataProvider().uri() dataall = self.sql_info(uri)
dataall = self.sql_info(uri) data = self.sql_to_xml(dataall)
data = self.sql_to_xml(dataall)
with open(resources_path('xml', 'dcat.xml'), encoding='utf8') as xml_file:
with open(resources_path('xml', 'dcat.xml'), encoding='utf8') as xml_file: xml_template = xml_file.read()
xml_template = xml_file.read()
xml = parseString(xml_template.format(language=data[0][0], content=data[0][1]))
xml = parseString(xml_template.format(language=data[0][0], content=data[0][1]))
data_str = xml.toprettyxml()
data_str = xml.toprettyxml()
with open(output_file[0], "w", encoding='utf8') as file_writer:
with open(output_file[0], "w", encoding='utf8') as file_writer: file_writer.write(data_str)
file_writer.write(data_str) iface.messageBar().pushSuccess(
iface.messageBar().pushSuccess( ("Export") + ' ' + output_format.label,
tr("Export") + ' ' + output_format.label, (
tr( "The metadata has been exported as {format} successfully in "
"The metadata has been exported as {format} successfully in " "<a href=\"{folder}\">{path}</a>").format(
"<a href=\"{folder}\">{path}</a>").format( format=output_format.label, folder=parent_folder, path=output_file_path)
format=output_format.label, folder=parent_folder, path=output_file_path) )
)
def save_auto_open_dock(self):
def save_auto_open_dock(self): """ Save settings about the dock. """
""" Save settings about the dock. """ self.settings.setValue("pgmetadata/auto_open_dock", self.auto_open_dock_action.isChecked())
self.settings.setValue("pgmetadata/auto_open_dock", self.auto_open_dock_action.isChecked()) def sql_to_xml(self,dataall):
def sql_to_xml(self,dataall): distribution=''
distribution='' for y in dataall[1]:
for y in dataall[1]: distribution = distribution + (
distribution = distribution + ( '<dcat:distribution>'+
'<dcat:distribution>'+ '<dcat:Distribution>'+
'<dcat:Distribution>'+ '<dct:title>{data}</dct:title>'.format(data=y[0])+
'<dct:title>{data}</dct:title>'.format(data=y[0])+ '<dcat:downloadURL>{data}</dcat:downloadURL>'.format(data=y[1])+
'<dcat:downloadURL>{data}</dcat:downloadURL>'.format(data=y[1])+ '<dcat:mediaType>{data}</dcat:mediaType>'.format(data=y[2])+
'<dcat:mediaType>{data}</dcat:mediaType>'.format(data=y[2])+ '<dct:format>{data}</dct:format>'.format(data=y[3])+
'<dct:format>{data}</dct:format>'.format(data=y[3])+ '<dct:bytesize>{data}</dct:bytesize>'.format(data=y[4])+
'<dct:bytesize>{data}</dct:bytesize>'.format(data=y[4])+ '</dcat:Distribution>'+
'</dcat:Distribution>'+ '</dcat:distribution>')
'</dcat:distribution>') publisher=''
publisher='' for z in dataall[2]:
for z in dataall[2]: publisher = publisher + (
publisher = publisher + ( '<dct:publisher>'+
'<dct:publisher>'+ '<foaf:Organization>'+
'<foaf:Organization>'+ '<foaf:name>{data}</foaf:name>'.format(data=z[1])+
'<foaf:name>{data}</foaf:name>'.format(data=z[1])+ '<foaf:mbox>{data}</foaf:mbox>'.format(data=z[3])+
'<foaf:mbox>{data}</foaf:mbox>'.format(data=z[3])+ '</foaf:Organization>'+
'</foaf:Organization>'+ '</dct:publisher>')
'</dct:publisher>') data_str = [[dataall[0][26],
data_str = [[dataall[0][26], '<dct:identifier>{data}</dct:identifier>'.format(data=dataall[0][1])+
'<dct:identifier>{data}</dct:identifier>'.format(data=dataall[0][1])+ '<dct:title>{data}</dct:title>'.format(data=dataall[0][4])+
'<dct:title>{data}</dct:title>'.format(data=dataall[0][4])+ '<dct:description>{data}</dct:description>'.format(data=dataall[0][5])+
'<dct:description>{data}</dct:description>'.format(data=dataall[0][5])+ '<dct:language>{data}</dct:language>'.format(data=dataall[0][26])+
'<dct:language>{data}</dct:language>'.format(data=dataall[0][26])+ '<dct:spatial>{data}</dct:spatial>'.format(data=dataall[0][28])+
'<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: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: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: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])+
'<dct:license>{data}</dct:license>'.format(data=dataall[0][13])+ distribution+
distribution+ publisher+
publisher+ '<dcat:theme>{data}</dcat:theme>'.format(data=", ".join(str(x) for x in dataall[0][24]))+
'<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]))+
'<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])]]
'<dct:accrualPeriodicity>{data}</dct:accrualPeriodicity>'.format(data=dataall[0][12])]]
return data_str
return data_str
@staticmethod
@staticmethod def sql_for_layer(uri, output_format: OutputFormats):
def sql_for_layer(uri, output_format: OutputFormats): """ Get the SQL query for a given layer and output format. """
""" Get the SQL query for a given layer and output format. """ locale = QgsSettings().value("locale/userLocale", QLocale().name())
locale = QgsSettings().value("locale/userLocale", QLocale().name()) locale = locale.split('_')[0].lower()
locale = locale.split('_')[0].lower()
if output_format == [OutputFormats.HTML,OutputFormats.DCAT]:
if output_format == [OutputFormats.HTML,OutputFormats.DCAT]: sql = (
sql = ( "SELECT pgmetadata.get_dataset_item_html_content('{schema}', '{table}', '{locale}');"
"SELECT pgmetadata.get_dataset_item_html_content('{schema}', '{table}', '{locale}');" ).format(schema=uri.schema(), table=uri.table(), locale=locale)
).format(schema=uri.schema(), table=uri.table(), locale=locale) else:
else: raise NotImplementedError('Output format is not yet implemented.')
raise NotImplementedError('Output format is not yet implemented.')
return sql
return sql
def layer_changed(self, layer):
def layer_changed(self, layer): """ When the layer has changed in the legend, we must check this new layer. """
""" When the layer has changed in the legend, we must check this new layer. """ self.current_datasource_uri = None
self.current_datasource_uri = None self.current_connection = None
self.current_connection = None self.ce_trouve_dans_psql(layer)
self.ce_trouve_dans_psql(layer)
def add_flatten_dataset_table(self):
def add_flatten_dataset_table(self): """ Add a flatten dataset table with all links and contacts. """
""" Add a flatten dataset table with all links and contacts. """ '''
''' connections, message = connections_list()
connections, message = connections_list() if not connections:
if not connections: LOGGER.critical(message)
LOGGER.critical(message) self.set_html_content('PgMetadata', message)
self.set_html_content('PgMetadata', message) return
return
if len(connections) > 1:
if len(connections) > 1: dialog = QInputDialog()
dialog = QInputDialog() dialog.setComboBoxItems(connections)
dialog.setComboBoxItems(connections) dialog.setWindowTitle(tr("Database"))
dialog.setWindowTitle(tr("Database")) dialog.setLabelText(tr("Choose the database to add the catalog"))
dialog.setLabelText(tr("Choose the database to add the catalog")) if not dialog.exec_():
if not dialog.exec_(): return
return connection_name = dialog.textValue()
connection_name = dialog.textValue() else:
else: connection_name = connections[0]
connection_name = connections[0]
metadata = QgsProviderRegistry.instance().providerMetadata('postgres')
metadata = QgsProviderRegistry.instance().providerMetadata('postgres') connection = metadata.findConnection(connection_name)
connection = metadata.findConnection(connection_name)
locale = QgsSettings().value("locale/userLocale", QLocale().name())
locale = QgsSettings().value("locale/userLocale", QLocale().name()) locale = locale.split('_')[0].lower()
locale = locale.split('_')[0].lower()
uri = QgsDataSourceUri(connection.uri())
uri = QgsDataSourceUri(connection.uri()) uri.setTable(f'(SELECT * FROM pgmetadata.export_datasets_as_flat_table(\'{locale}\'))')
uri.setTable(f'(SELECT * FROM pgmetadata.export_datasets_as_flat_table(\'{locale}\'))') uri.setKeyColumn('uid')
uri.setKeyColumn('uid')
layer = QgsVectorLayer(uri.uri(), '{} - {}'.format(tr("Catalog"), connection_name), 'postgres')
layer = QgsVectorLayer(uri.uri(), '{} - {}'.format(tr("Catalog"), connection_name), 'postgres') QgsProject.instance().addMapLayer(layer)
QgsProject.instance().addMapLayer(layer) '''
'''
@staticmethod
@staticmethod def open_external_help():
def open_external_help(): QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
@staticmethod
@staticmethod def open_link(url):
def open_link(url): QDesktopServices.openUrl(url)
QDesktopServices.openUrl(url)
def set_html_content(self, title=None, body=None):
def set_html_content(self, title=None, body=None): """ Set the content in the dock. """
""" Set the content in the dock. """ #link_logo=resources_path('icons', 'CEN_RA.png')
#link_logo=resources_path('icons', 'CEN_RA.png') css_file = resources_path('css', 'dock.css')
css_file = resources_path('css', 'dock.css') with open(css_file, 'r', encoding='utf8') as f:
with open(css_file, 'r', encoding='utf8') as f: css = f.read()
css = f.read()
html = '<html><head>'
html = '<html><head>' #html += '<script src="http://ignf.github.io/geoportal-sdk/latest/dist/2d/GpSDK2D.js" defer ></script>'
#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 += '<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 += '<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 += '<script src="file:///C:/Users/tlaveille/Desktop/maps.js" defer></script>' #html += '<noscript>Your browser does not support JavaScript!</noscript>'
#html += '<noscript>Your browser does not support JavaScript!</noscript>' if title:
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)
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:
if body: html += body
html += body
html += '</body></html>'
html += '</body></html>'
# It must be a file, even if it does not exist on the file system.
# 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'))
base_url = QUrl.fromLocalFile(resources_path('images', 'must_be_a_file.png')) self.viewer.setHtml(html, base_url)
self.viewer.setHtml(html, base_url)
def ce_trouve_dans_psql(self,layer):
def ce_trouve_dans_psql(self,layer): try:
try: uri = layer.dataProvider().uri()
uri = layer.dataProvider().uri() except:
except: self.default_html_content_not_pg_layer()
self.default_html_content_not_pg_layer() self.save_button.setEnabled(False)
self.save_button.setEnabled(False) uri=''
uri='' if uri != '':
if uri != '': if not uri.table():
if not uri.table(): layertype = layer.providerType().lower()
self.default_html_content_not_pg_layer() if layertype == 'wms' or layertype == 'wfs':
self.save_button.setEnabled(False) self.set_html_to_wms(layer)
else: else:
data_count = self.sql_check(uri) self.default_html_content_not_pg_layer()
#print(data_count) self.save_button.setEnabled(False)
if data_count == 0: else:
self.default_html_content_not_metadata() data_count = self.sql_check(uri)
self.save_button.setEnabled(False) #print(data_count)
else: if data_count == 0:
self.build_html_content(layer,uri) self.default_html_content_not_metadata()
self.save_button.setEnabled(True) self.save_button.setEnabled(False)
else:
def build_html_content(self,layer,uri): self.build_html_content(layer,uri)
body = '' self.save_button.setEnabled(True)
dataall=self.sql_info(uri) def build_html_content(self,layer,uri):
data=dataall[0] body = ''
data_url=dataall[1]
data_contact=dataall[2] dataall=self.sql_info(uri)
#print(len(data_url)) data=dataall[0]
data_collonne=[field.name() for field in layer.dataProvider().fields()] data_url=dataall[1]
data_contact=dataall[2]
body += '<div><h3>Identification</h3><table class="table table-condensed">' #print(len(data_url))
body += '<tr><th>Titre</th><td>{data[4]}</td></tr>'.format(data=data) data_collonne=[field.name() for field in layer.dataProvider().fields()]
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 += '<div><h3>Identification</h3><table class="table table-condensed">'
body += '<tr><th>Thèmes</th><td>{data}</td></tr>'.format(data=(", ".join(str(x) for x in data[24]))) body += '<tr><th>Titre</th><td>{data[4]}</td></tr>'.format(data=data)
body += '<tr><th>Mots-clés</th><td>{data[7]}</td></tr>'.format(data=data) body += '<tr><th>Description</th><td>{data[5]}</td></tr>'.format(data=data)
body += '<tr><th>Dernier mise à jour</th><td>{data[23]}</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>Langue</th><td>{data[26]}</td></tr>'.format(data=data) body += '<tr><th>Thèmes</th><td>{data}</td></tr>'.format(data=(", ".join(str(x) for x in data[24])))
body += '</table></div>' 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 += '<div><h3>Properties spatial</h3><table class="table table-condensed">' body += '<tr><th>Langue</th><td>{data[26]}</td></tr>'.format(data=data)
body += '<tr><th>Niveau</th><td>{data[8]}</td></tr>'.format(data=data) body += '</table></div>'
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 += '<div><h3>Properties spatial</h3><table class="table table-condensed">'
body += '<tr><th>Nombre d\'entités </th><td>{data[15]}</td></tr>'.format(data=data) body += '<tr><th>Niveau</th><td>{data[8]}</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>Echelle minimum</th><td>{data[9]}</td></tr>'.format(data=data)
body += '<tr><th>Nom de projection</th><td>{data[17]}</td></tr>'.format(data=data) body += '<tr><th>Echelle maximum</th><td>{data[10]}</td></tr>'.format(data=data)
body += '<tr><th>ID de projection</th><td>{data[18]}</td></tr>'.format(data=data) body += '<tr><th>Nombre d\'entités </th><td>{data[15]}</td></tr>'.format(data=data)
body += '<tr><th>Emprise</th><td>{data[28]}</td></tr>'.format(data=data) body += '<tr><th>Type de géométrie</th><td>{data[16]}</td></tr>'.format(data=data)
body += '</table></div>' 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 += '<div id="map"></div>' body += '<tr><th>Emprise</th><td>{data[28]}</td></tr>'.format(data=data)
body += '</table></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 += '<div id="map"></div>'
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 += '<div><h3>Publication</h3><table class="table table-condensed">'
body += '<tr><th>Licence attribué</th><td>{data[25]}</td></tr>'.format(data=data) body += '<tr><th>Date</th><td>{data[11]}</td></tr>'.format(data=data)
body += '<tr><th>Restriction</th><td>{data[14]}</td></tr>'.format(data=data) body += '<tr><th>Fréquence de mise à jour</th><td>{data[12]}</td></tr>'.format(data=data)
body += '</table></div>' 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 += '<div><h3>Lien</h3><table class="table table-condensed table-striped table-bordered">' body += '<tr><th>Restriction</th><td>{data[14]}</td></tr>'.format(data=data)
body += '<tr><th>Type</th><th>URL</th><th>Type MIME</th><th>Format</th><th>Taille</th></tr>' body += '</table></div>'
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 += '<div><h3>Lien</h3><table class="table table-condensed table-striped table-bordered">'
body += '</table></div>' 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 += '<div><h3>Liste des champs</h3><table class="table table-condensed table-striped table-bordered">' 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)
for collonne in data_collonne: body += '</table></div>'
body += '<tr><th>{collonne}</th><td>{defini}</td></tr>'.format(collonne=collonne,defini='') '''
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 += '<div><h3>Contacts</h3><table class="table table-condensed table-striped table-bordered">' body += '<tr><th>{collonne}</th><td>{defini}</td></tr>'.format(collonne=collonne,defini='')
body += '<tr><th>Rôle</th><th>Nom</th><th>Organisation</th><th>Email</th><th>Télèphone</th></tr>' body += '</table></div>'
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 += '<div><h3>Contacts</h3><table class="table table-condensed table-striped table-bordered">'
body += '</table></div>' 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 += '<div><h3>Metadata</h3><table class="table table-condensed">' 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 += '<tr><th>Table</th><td>{data[2]}</td></tr>'.format(data=data) body += '</table></div>'
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 += '<div><h3>Metadata</h3><table class="table table-condensed">'
body += '<tr><th>Date de modification</th><td>{data[21]}</td></tr>'.format(data=data) body += '<tr><th>Table</th><td>{data[2]}</td></tr>'.format(data=data)
body += '<tr><th>Encodage</th><td>{data[27]}</td></tr>'.format(data=data) body += '<tr><th>Schema</th><td>{data[3]}</td></tr>'.format(data=data)
body += '<tr><th>UUID</th><td>{data[1]}</td></tr>'.format(data=data) body += '<tr><th>Date de création</th><td>{data[20]}</td></tr>'.format(data=data)
body += '</table></div>' 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)
self.set_html_content( body += '<tr><th>UUID</th><td>{data[1]}</td></tr>'.format(data=data)
layer.name(), body) body += '</table></div>'
def default_html_content_not_pg_layer(self): self.set_html_content(
""" When it's not a PostgreSQL layer. """ layer.name(), body)
self.set_html_content(
'CenRa Metadata', tr('Vous devez cliquer sur une couche dans la légende qui est stockée dans PostgreSQL.')) def set_html_to_wms(self,layer):
def default_html_content_not_metadata(self): self.set_html_content(
self.set_html_content( 'CenRa Metadata',(layer.htmlMetadata()))
'CenRa Metadata', tr('La couche ne contien pas de métadonnée.')) def default_html_content_not_pg_layer(self):
""" When it's not a PostgreSQL layer. """
def sql_check(self,uri): self.set_html_content(
cur=login_base() 'CenRa Metadata', ('Vous devez cliquer sur une couche dans la légende qui est stockée dans PostgreSQL.'))
table = uri.table() def default_html_content_not_metadata(self):
schema = uri.schema() self.set_html_content(
'CenRa Metadata', ('La couche ne contien pas de métadonnée.'))
sql_count = """SELECT count(uid) FROM metadata.dataset
WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';""" def sql_check(self,uri):
cur=login_base()
cur.execute(sql_count) table = uri.table()
data_count = cur.fetchall() schema = uri.schema()
cur.close()
return data_count[0][0] sql_count = """SELECT count(uid) FROM metadata.dataset
WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';"""
def sql_info(self,uri):
cur=login_base() cur.execute(sql_count)
table = uri.table() data_count = cur.fetchall()
schema = uri.schema() cur.close()
#[s for s in iface.activeLayer().source().split(" ") if "dbname" in s][0].split("'")[1] return data_count[0][0]
sql_find = """SELECT *,right(left(st_astext(geom,2),-2),-9) FROM metadata.dataset
WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';""" def sql_info(self,uri):
cur.execute(sql_find) cur=login_base()
data_general = cur.fetchall() table = uri.table()
sql_findurl = """SELECT type,url,mime,format,taille FROM metadata.dataurl WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';""" schema = uri.schema()
cur.execute(sql_findurl) #[s for s in iface.activeLayer().source().split(" ") if "dbname" in s][0].split("'")[1]
data_url = cur.fetchall() sql_find = """SELECT *,right(left(st_astext(geom,2),-2),-9) FROM metadata.dataset
sql_findcontact = """SELECT role,nom,organisation,email,telephone FROM metadata.datacontact WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';""" WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';"""
cur.execute(sql_findcontact) cur.execute(sql_find)
data_contact = cur.fetchall() data_general = cur.fetchall()
cur.close() sql_findurl = """SELECT type,url,mime,format,taille FROM metadata.dataurl WHERE schema_name LIKE '"""+schema+"""' AND table_name LIKE '"""+table+"""';"""
return data_general[0],data_url,data_contact 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

View File

@ -6,7 +6,7 @@
name=CenRa_Metabase name=CenRa_Metabase
qgisMinimumVersion=3.0 qgisMinimumVersion=3.0
description=CenRa_METABASE description=CenRa_METABASE
version=1.2 version=1.3
author=Conservatoire d'Espaces Naturels de Rhône-Alpes author=Conservatoire d'Espaces Naturels de Rhône-Alpes
email=si_besoin@cen-rhonealpes.fr email=si_besoin@cen-rhonealpes.fr
@ -21,7 +21,7 @@ tracker=https://gitea.cenra-outils.org/api/v1/repos/CEN-RA/Plugin_QGIS/issues
hasProcessingProvider=no hasProcessingProvider=no
# Uncomment the following line and add your changelog: # Uncomment the following line and add your changelog:
changelog=<h2>CenRa_Metabase:</h2></br><p><h3>07/10/2024 - Version 1.2: </h3> - Correctif de bug.</p></br><p><h3>03/10/2024 - Version 1.1: </h3> - Remonte la fênetre dans la pille.</p></br><p><h3>26/08/2024 - Version 1.0: </h3> - Lancement du plugin CenRa_Metabase </p></br> changelog=<h2>CenRa_Metabase:</h2></br><p><h3>08/10/2024 - Version 1.3: </h3> - Lecture de métadonnée des flux WMS/WFS.</p></br><p><h3>07/10/2024 - Version 1.2: </h3> - Correctif de bug.</p></br><p><h3>03/10/2024 - Version 1.1: </h3> - Remonte la fênetre dans la pille.</p></br><p><h3>26/08/2024 - Version 1.0: </h3> - Lancement du plugin CenRa_Metabase </p></br>
# Tags are comma separated with spaces allowed # Tags are comma separated with spaces allowed
tags=python tags=python