Skip to content

Commit 004f50c

Browse files
committed
Log
1 parent 15dc417 commit 004f50c

File tree

4 files changed

+401
-118
lines changed

4 files changed

+401
-118
lines changed

oqtopus/core/package_prepare_task.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import logging
21
import os
32
import shutil
43
import zipfile
54

65
import requests
7-
from qgis.PyQt.QtCore import QFileInfo, QThread, pyqtSignal
6+
from qgis.PyQt.QtCore import QThread, pyqtSignal
87

98
from ..utils.plugin_utils import PluginUtils
109

@@ -87,10 +86,10 @@ def __download_module_version(self, module_version):
8786

8887
self.__checkForCanceled()
8988

90-
logging.info(f"Downloading from '{url}' to '{self.zip_file}'")
89+
# logging.info(f"Downloading from '{url}' to '{self.zip_file}'")
9190
data_size = 0
9291
with open(self.zip_file, "wb") as file:
93-
next_emit_threshold = 5 * 1024 * 1024 # 5MB threshold
92+
next_emit_threshold = 10 * 1024 * 1024 # 10MB threshold
9493
for data in response.iter_content(chunk_size=None):
9594
file.write(data)
9695

@@ -99,20 +98,23 @@ def __download_module_version(self, module_version):
9998
data_size += len(data)
10099
if data_size >= next_emit_threshold: # Emit signal when threshold is exceeded
101100
self.signalPackagingProgress.emit(data_size)
102-
next_emit_threshold += 5 * 1024 * 1024 # Update to the next threshold
101+
next_emit_threshold += 10 * 1024 * 1024 # Update to the next threshold
103102

104103
def __extract_zip_file(self, zip_file):
105104
temp_dir = PluginUtils.plugin_temp_path()
106-
self.package_dir = os.path.join(temp_dir, QFileInfo(zip_file).baseName())
107-
if os.path.exists(self.package_dir):
108-
shutil.rmtree(self.package_dir)
109-
110-
logging.info(f"Extracting package '{zip_file}' to '{self.package_dir}'")
111105

112106
# Unzip the file to plugin temp dir
113107
try:
114108
with zipfile.ZipFile(zip_file, "r") as zip_ref:
109+
# Find the top-level directory
110+
zip_dirname = zip_ref.namelist()[0].split("/")[0]
111+
self.package_dir = os.path.join(temp_dir, zip_dirname)
112+
113+
if os.path.exists(self.package_dir):
114+
shutil.rmtree(self.package_dir)
115+
115116
zip_ref.extractall(temp_dir)
117+
116118
except zipfile.BadZipFile:
117119
raise Exception(self.tr(f"The selected file '{zip_file}' is not a valid zip archive."))
118120

oqtopus/gui/main_dialog.py

Lines changed: 192 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
#
2323
# ---------------------------------------------------------------------
2424

25+
import logging
2526
import os
27+
import shutil
2628

2729
import psycopg
2830
from qgis.PyQt.QtCore import Qt, QUrl
@@ -34,7 +36,7 @@
3436
from ..libs.pum.config import PumConfig
3537
from ..libs.pum.schema_migrations import SchemaMigrations
3638
from ..libs.pum.upgrader import Upgrader
37-
from ..utils.plugin_utils import PluginUtils
39+
from ..utils.plugin_utils import LoggingBridge, PluginUtils
3840
from ..utils.qt_utils import OverrideCursor, QtUtils
3941
from .database_create_dialog import DatabaseCreateDialog
4042
from .database_duplicate_dialog import DatabaseDuplicateDialog
@@ -53,6 +55,11 @@ class MainDialog(QDialog, DIALOG_UI):
5355
def __init__(self, modules_registry, parent=None):
5456
QDialog.__init__(self, parent)
5557
self.setupUi(self)
58+
59+
self.logger = logging.getLogger()
60+
self.loggingBridge = LoggingBridge(self.__logged_line)
61+
self.logger.addHandler(self.loggingBridge)
62+
5663
self.buttonBox.rejected.connect(self.__closeDialog)
5764
self.buttonBox.helpRequested.connect(self.__helpRequested)
5865

@@ -61,8 +68,10 @@ def __init__(self, modules_registry, parent=None):
6168

6269
self.__database_connection = None
6370

64-
self.__pum_config = None
71+
self.__package_dir = None
6572
self.__data_model_dir = None
73+
self.__pum_config = None
74+
self.__project_file = None
6675

6776
# Init GUI Modules
6877
self.__initGuiModules()
@@ -73,12 +82,17 @@ def __init__(self, modules_registry, parent=None):
7382
# Init GUI Module Info
7483
self.__initGuiModuleInfo()
7584

85+
# Init GUI Project
86+
self.__initGuiProject()
87+
7688
self.__packagePrepareTask = PackagePrepareTask(self)
7789
self.__packagePrepareTask.finished.connect(self.__packagePrepareTaskFinished)
7890
self.__packagePrepareTask.signalPackagingProgress.connect(
7991
self.__packagePrepareTaskProgress
8092
)
8193

94+
self.logger.info("Ready.")
95+
8296
def __initGuiModules(self):
8397
self.module_module_comboBox.clear()
8498
self.module_module_comboBox.addItem(self.tr("Please select a module"), None)
@@ -131,6 +145,17 @@ def __initGuiModuleInfo(self):
131145
self.moduleInfo_install_pushButton.clicked.connect(self.__installModuleClicked)
132146
self.moduleInfo_upgrade_pushButton.clicked.connect(self.__upgradeModuleClicked)
133147

148+
def __initGuiProject(self):
149+
self.project_install_pushButton.clicked.connect(self.__projectInstallClicked)
150+
self.project_seeChangelog_pushButton.clicked.connect(self.__projectSeeChangelogClicked)
151+
152+
def __logged_line(self, line):
153+
self.logs_plainTextEdit.appendPlainText(line)
154+
155+
# Automatically scroll to the bottom of the logs
156+
scroll_bar = self.logs_plainTextEdit.verticalScrollBar()
157+
scroll_bar.setValue(scroll_bar.maximum())
158+
134159
def __closeDialog(self):
135160
if self.__packagePrepareTask.isRunning():
136161
self.__packagePrepareTask.cancel()
@@ -139,7 +164,9 @@ def __closeDialog(self):
139164
self.accept()
140165

141166
def __helpRequested(self):
142-
QDesktopServices.openUrl(QUrl("https://github.com/oqtopus/Oqtopus"))
167+
help_page = "https://github.com/oqtopus/Oqtopus"
168+
self.logger.info(f"Opening help page {help_page}")
169+
QDesktopServices.openUrl(QUrl(help_page))
143170

144171
def __loadDatabaseInformations(self):
145172
self.db_servicesConfigFilePath_label.setText(pgserviceparser.conf_path().as_posix())
@@ -211,8 +238,17 @@ def __moduleVersionChanged(self, index):
211238
if current_module_version is None:
212239
return
213240

214-
self.__pum_config = None
241+
self.__package_dir = None
215242
self.__data_model_dir = None
243+
self.__pum_config = None
244+
self.__project_file = None
245+
246+
loading_text = self.tr(
247+
f"Loading package for module '{self.module_module_comboBox.currentText()}' version '{current_module_version.display_name()}'..."
248+
)
249+
self.module_information_label.setText(loading_text)
250+
QtUtils.resetForegroundColor(self.module_information_label)
251+
self.logger.info(loading_text)
216252

217253
if self.__packagePrepareTask.isRunning():
218254
self.__packagePrepareTask.cancel()
@@ -263,8 +299,10 @@ def __moduleBrowseZipClicked(self):
263299

264300
def __loadModuleFromZip(self, filename):
265301

266-
self.__pum_config = None
302+
self.__package_dir = None
267303
self.__data_model_dir = None
304+
self.__pum_config = None
305+
self.__project_file = None
268306

269307
if self.__packagePrepareTask.isRunning():
270308
self.__packagePrepareTask.cancel()
@@ -273,16 +311,31 @@ def __loadModuleFromZip(self, filename):
273311
self.__packagePrepareTask.startFromZip(filename)
274312

275313
def __packagePrepareTaskFinished(self):
314+
self.logger.info("Load package task finished")
276315

277316
if self.__packagePrepareTask.lastError is not None:
317+
error_text = f"Can't load module package:\n{self.__packagePrepareTask.lastError}"
318+
self.module_information_label.setText(error_text)
319+
QtUtils.setForegroundColor(self.module_information_label, self.COLOR_WARNING)
278320
QMessageBox.critical(
279321
self,
280322
self.tr("Error"),
281-
self.tr(f"Can't load module package:\n{self.__packagePrepareTask.lastError}"),
323+
self.tr(error_text),
282324
)
283325
return
284326

285-
self.__data_model_dir = os.path.join(self.__packagePrepareTask.package_dir, "datamodel")
327+
self.__package_dir = self.__packagePrepareTask.package_dir
328+
self.logger.info(f"Package loaded into '{self.__package_dir}'")
329+
self.module_information_label.setText(self.__package_dir)
330+
QtUtils.resetForegroundColor(self.module_information_label)
331+
332+
self.__packagePrepareGetPUMConfig()
333+
334+
self.__packagePrepareGetProjectFilename()
335+
336+
def __packagePrepareGetPUMConfig(self):
337+
338+
self.__data_model_dir = os.path.join(self.__package_dir, "datamodel")
286339
pumConfigFilename = os.path.join(self.__data_model_dir, ".pum.yaml")
287340
if not os.path.exists(pumConfigFilename):
288341
QMessageBox.critical(
@@ -324,8 +377,47 @@ def __packagePrepareTaskFinished(self):
324377
self.moduleInfo_stackedWidget_pageInstall
325378
)
326379

380+
def __packagePrepareGetProjectFilename(self):
381+
# Search for QGIS project file in self.__package_dir
382+
project_file_dir = os.path.join(self.__package_dir, "project")
383+
384+
# Check if the directory exists
385+
if not os.path.exists(project_file_dir):
386+
self.project_info_label.setText(
387+
self.tr(f"Project directory '{project_file_dir}' does not exist.")
388+
)
389+
QtUtils.setForegroundColor(self.project_info_label, self.COLOR_WARNING)
390+
QtUtils.setFontItalic(self.db_database_label, True)
391+
return
392+
393+
self.__project_file = None
394+
for root, dirs, files in os.walk(project_file_dir):
395+
for file in files:
396+
if file.endswith(".qgz") or file.endswith(".qgs"):
397+
self.__project_file = os.path.join(root, file)
398+
break
399+
400+
if self.__project_file:
401+
break
402+
403+
if self.__project_file is None:
404+
self.project_info_label.setText(
405+
self.tr(f"No QGIS project file (.qgz or .qgs) found into {project_file_dir}."),
406+
)
407+
QtUtils.setForegroundColor(self.project_info_label, self.COLOR_WARNING)
408+
QtUtils.setFontItalic(self.db_database_label, True)
409+
return
410+
411+
self.project_info_label.setText(
412+
self.tr(self.__project_file),
413+
)
414+
QtUtils.setForegroundColor(self.project_info_label, self.COLOR_GREEN)
415+
QtUtils.setFontItalic(self.db_database_label, False)
416+
327417
def __packagePrepareTaskProgress(self, progress):
328-
print(f"Progress: {progress}")
418+
loading_text = self.tr("Load package task running...")
419+
self.logger.info(loading_text)
420+
self.module_information_label.setText(loading_text)
329421

330422
def __seeChangeLogClicked(self):
331423
current_module_version = self.module_version_comboBox.currentData()
@@ -354,7 +446,9 @@ def __seeChangeLogClicked(self):
354446
)
355447
return
356448

357-
QDesktopServices.openUrl(QUrl(current_module_version.html_url))
449+
changelog_url = current_module_version.html_url
450+
self.logger.info(f"Opening changelog URL: {changelog_url}")
451+
QDesktopServices.openUrl(QUrl(changelog_url))
358452

359453
def __serviceChanged(self, index=None):
360454
if self.db_services_comboBox.currentText() == "":
@@ -536,3 +630,92 @@ def __createAndGrantRolesClicked(self):
536630
return
537631

538632
raise NotImplementedError("Create and grant roles is not implemented yet")
633+
634+
def __projectInstallClicked(self):
635+
636+
if self.__current_module is None:
637+
QMessageBox.warning(
638+
self,
639+
self.tr("Error"),
640+
self.tr("Please select a module and version first."),
641+
)
642+
return
643+
644+
current_module_version = self.module_version_comboBox.currentData()
645+
if current_module_version is None:
646+
QMessageBox.warning(
647+
self,
648+
self.tr("Error"),
649+
self.tr("Please select a module version first."),
650+
)
651+
return
652+
653+
if self.__package_dir is None:
654+
QMessageBox.critical(
655+
self,
656+
self.tr("Error"),
657+
self.tr("No valid package directory available."),
658+
)
659+
return
660+
661+
# Search for QGIS project file in self.__package_dir
662+
project_file_dir = os.path.join(self.__package_dir, "project")
663+
664+
# Check if the directory exists
665+
if not os.path.exists(project_file_dir):
666+
QMessageBox.critical(
667+
self,
668+
self.tr("Error"),
669+
self.tr(f"Project directory '{project_file_dir}' does not exist."),
670+
)
671+
return
672+
673+
self.__project_file = None
674+
for root, dirs, files in os.walk(project_file_dir):
675+
print(f"Searching for QGIS project file in {root}: {files}")
676+
for file in files:
677+
if file.endswith(".qgz") or file.endswith(".qgs"):
678+
self.__project_file = os.path.join(root, file)
679+
break
680+
681+
if self.__project_file:
682+
break
683+
684+
if self.__project_file is None:
685+
QMessageBox.critical(
686+
self,
687+
self.tr("Error"),
688+
self.tr(f"No QGIS project file (.qgz or .qgs) found into {project_file_dir}."),
689+
)
690+
return
691+
692+
install_destination = QFileDialog.getExistingDirectory(
693+
self,
694+
self.tr("Select installation directory"),
695+
"",
696+
QFileDialog.ShowDirsOnly,
697+
)
698+
699+
if not install_destination:
700+
return
701+
702+
# Copy the project file to the selected directory
703+
try:
704+
shutil.copy(self.__project_file, install_destination)
705+
QMessageBox.information(
706+
self,
707+
self.tr("Project installed"),
708+
self.tr(
709+
f"Project file '{self.__project_file}' has been copied to '{install_destination}'."
710+
),
711+
)
712+
except Exception as e:
713+
QMessageBox.critical(
714+
self,
715+
self.tr("Error"),
716+
self.tr(f"Failed to copy project file: {e}"),
717+
)
718+
return
719+
720+
def __projectSeeChangelogClicked(self):
721+
self.__seeChangeLogClicked()

0 commit comments

Comments
 (0)