mirror of
https://github.com/ARUP-CAS/aiscr-qgis-amcr-viewer.git
synced 2026-06-19 04:12:55 +02:00
Feature/aktualizace heslaru (#32)
* přechod od statického hesláře k dynamickému načítání z OAI-PMH API AMČR * aplikace načítání heslářů a task management (backend) * frontend + debugging * aktualizace přibaleného hesláře * kosmetické drobnosti * ošetření speciální případů při stahování hesláře (katastr, okres) + s tím spojená aktualizace přiloženého hesláře
This commit is contained in:
+68
-31
@@ -1,14 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from qgis.PyQt.QtWidgets import (QDialog, QVBoxLayout, QFormLayout,
|
||||
from qgis.PyQt.QtWidgets import (QDialog, QVBoxLayout,
|
||||
QLineEdit, QDialogButtonBox,
|
||||
QCheckBox, QGroupBox, QPushButton,
|
||||
QListWidget, QListWidgetItem, QHBoxLayout,
|
||||
QLabel, QMessageBox, QApplication, QWidget)
|
||||
QMessageBox)
|
||||
from qgis.PyQt.QtCore import Qt
|
||||
from qgis.core import QgsTask, QgsApplication, QgsMessageLog, Qgis
|
||||
from .amcr_codelists import (OBDOBI, TYP_AKCE, KRAJE, AREAL, ORGANIZACE,
|
||||
OKRESY, KATASTRY, VEDOUCI, PIAN_PRESNOST, TYP_LOKALITY,
|
||||
DRUH_LOKALITY, JISTOTA, LOKALITA_ZACHOVALOST,
|
||||
download_vedouci, refresh_vedouci_cache)
|
||||
download_heslare, refresh_globals)
|
||||
|
||||
class UpdateCodelistsTask(QgsTask):
|
||||
def __init__(self, description):
|
||||
super().__init__(description, QgsTask.CanCancel)
|
||||
self.success = False
|
||||
self.exception = None
|
||||
|
||||
def run(self):
|
||||
"""Tato část běží ve vedlejším vlákně."""
|
||||
try:
|
||||
# Voláme upravenou funkci
|
||||
self.success = download_heslare(task=self)
|
||||
return self.success
|
||||
except Exception as e:
|
||||
self.exception = e
|
||||
return False
|
||||
|
||||
def finished(self, result):
|
||||
"""Tato část běží v hlavním vlákně po skončení run()."""
|
||||
if result:
|
||||
# Teď bezpečně aktualizujeme globální proměnné v hlavním vlákně
|
||||
refresh_globals()
|
||||
QgsMessageLog.logMessage("Hesláře AMČR byly úspěšně aktualizovány.", "AMČR", Qgis.Info)
|
||||
else:
|
||||
if self.isCanceled():
|
||||
QgsMessageLog.logMessage("Aktualizace heslářů byla zrušena.", "AMČR", Qgis.Warning)
|
||||
else:
|
||||
QgsMessageLog.logMessage(f"Chyba aktualizace: {self.exception}", "AMČR", Qgis.Critical)
|
||||
|
||||
class FilterableSelectionDialog(QDialog):
|
||||
"""
|
||||
@@ -99,9 +128,8 @@ class AmcrFilterDialog(QDialog):
|
||||
|
||||
# Determines if we are fetching 'akce' (projects) or 'lokalita' (locations)
|
||||
self.typ_dat = typ_dat
|
||||
|
||||
|
||||
|
||||
|
||||
# Cache dictionary to store selected codes for each category
|
||||
self.selection_cache = {
|
||||
'organizace': [], 'kraj': [], 'obdobi': [], 'areal': [],
|
||||
@@ -143,14 +171,8 @@ class AmcrFilterDialog(QDialog):
|
||||
if self.typ_dat == "akce":
|
||||
self.picker_org = self.setup_picker("Organizace", 'organizace', ORGANIZACE)
|
||||
layout.addWidget(self.picker_org)
|
||||
|
||||
# Button to fetch fresh project leaders from the API
|
||||
self.btn_update_vedouci = QPushButton("🔄")
|
||||
self.btn_update_vedouci.setToolTip("Aktualizovat seznam vedoucích z API")
|
||||
self.btn_update_vedouci.setFixedWidth(30)
|
||||
self.btn_update_vedouci.clicked.connect(self.action_update_vedouci)
|
||||
|
||||
self.picker_vedouci = self.setup_picker("Vedoucí výzkumu", 'vedouci', VEDOUCI, extra_btn=self.btn_update_vedouci)
|
||||
self.picker_vedouci = self.setup_picker("Vedoucí výzkumu", 'vedouci', VEDOUCI)
|
||||
layout.addWidget(self.picker_vedouci)
|
||||
|
||||
# Type of event
|
||||
@@ -188,10 +210,18 @@ class AmcrFilterDialog(QDialog):
|
||||
# Pushes everything above to the top
|
||||
layout.addStretch(1)
|
||||
|
||||
# Main dialog OK/Cancel buttons
|
||||
buttons = QDialogButtonBox(
|
||||
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
||||
)
|
||||
# Main dialog OK/Cancel/Update buttons
|
||||
|
||||
buttons = QDialogButtonBox()
|
||||
|
||||
self.btn_update = QPushButton("Aktualizovat hesláře 🔄")
|
||||
self.btn_update.setToolTip("Provede kompletní aktualizaci heslářů AMČR. Toto bude trvat pár minut.")
|
||||
self.btn_update.clicked.connect(self.action_update_heslare)
|
||||
|
||||
buttons.addButton(self.btn_update, QDialogButtonBox.ButtonRole.ActionRole)
|
||||
buttons.addButton(QDialogButtonBox.StandardButton.Ok)
|
||||
buttons.addButton(QDialogButtonBox.StandardButton.Cancel)
|
||||
|
||||
buttons.accepted.connect(self.accept)
|
||||
buttons.rejected.connect(self.reject)
|
||||
layout.addWidget(buttons)
|
||||
@@ -219,7 +249,7 @@ class AmcrFilterDialog(QDialog):
|
||||
# Nested function that handles opening the dialog and saving results
|
||||
def open_dialog():
|
||||
dlg = FilterableSelectionDialog(label_text, data_source, self.selection_cache[cache_key], self)
|
||||
if dlg.exec() == QDialog.DialogCode.Accepted: # PyQt6: DialogCode
|
||||
if dlg.exec() == QDialog.DialogCode.Accepted:
|
||||
codes, labels = dlg.get_selected_codes()
|
||||
# Update local cache with selected IDs
|
||||
self.selection_cache[cache_key] = codes
|
||||
@@ -246,21 +276,28 @@ class AmcrFilterDialog(QDialog):
|
||||
row_widget.setLayout(row_layout)
|
||||
return row_widget
|
||||
|
||||
def action_update_vedouci(self):
|
||||
# Change cursor to loading state to indicate background task
|
||||
QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor)
|
||||
try:
|
||||
success, msg = download_vedouci()
|
||||
if success:
|
||||
count = refresh_vedouci_cache()
|
||||
QMessageBox.information(self, "Úspěch", f"{msg}\nNyní je v paměti {count} osob.")
|
||||
def action_update_heslare(self):
|
||||
# Vytvoření instance tasku
|
||||
task = UpdateCodelistsTask("Aktualizace heslářů AMČR")
|
||||
|
||||
# Povolíme tlačítko zpět bez ohledu na výsledek
|
||||
task.taskCompleted.connect(lambda: self.btn_update.setEnabled(True))
|
||||
task.taskTerminated.connect(lambda: self.btn_update.setEnabled(True))
|
||||
|
||||
task.taskCompleted.connect(lambda: QMessageBox.information(self, "Hotovo", "Hesláře byly úspěšně aktualizovány."))
|
||||
|
||||
# Ošetření, aby se přesně ukázala případná chyba
|
||||
def on_error():
|
||||
if task.exception:
|
||||
# Tohle ti přesně řekne, na čem to teď padá (např. PermissionError)
|
||||
msg = f"Aktualizace selhala z důvodu chyby:\n{str(task.exception)}"
|
||||
else:
|
||||
QMessageBox.warning(self, "Chyba", f"Nepodařilo se stáhnout data:\n{msg}")
|
||||
except Exception as e:
|
||||
QMessageBox.critical(self, "Chyba", str(e))
|
||||
finally:
|
||||
# Safely restore the normal cursor even if an error occurs
|
||||
QApplication.restoreOverrideCursor()
|
||||
msg = "Aktualizace byla zrušena uživatelem."
|
||||
QMessageBox.warning(self, "Chyba / Zrušeno", msg)
|
||||
|
||||
task.taskTerminated.connect(on_error)
|
||||
|
||||
QgsApplication.taskManager().addTask(task)
|
||||
|
||||
def get_bbox(self):
|
||||
return "true" if self.chk_bbox.isChecked() else "false"
|
||||
|
||||
Reference in New Issue
Block a user