Skip to content

Commit 6ac98e3

Browse files
committed
Logging
1 parent 3687143 commit 6ac98e3

File tree

6 files changed

+213
-86
lines changed

6 files changed

+213
-86
lines changed

oqtopus/core/module_version.py

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import os
2-
31
import requests
42
from qgis.PyQt.QtCore import QDateTime, Qt
53

@@ -12,6 +10,12 @@ class Type:
1210
BRANCH = "branch"
1311
PULL_REQUEST = "pull_request"
1412

13+
class Asset:
14+
def __init__(self, name: str, download_url: str, size: int):
15+
self.name = name
16+
self.download_url = download_url
17+
self.size = size
18+
1519
def __init__(
1620
self,
1721
organisation,
@@ -29,6 +33,10 @@ def __init__(
2933
self.prerelease = False
3034
self.html_url = None
3135

36+
self.asset_datamodel = None
37+
self.asset_project = None
38+
self.asset_plugin = None
39+
3240
if self.type == ModuleVersion.Type.RELEASE:
3341
self.__parse_release(json_payload)
3442
elif self.type == ModuleVersion.Type.BRANCH:
@@ -52,23 +60,6 @@ def display_name(self):
5260

5361
return self.name
5462

55-
def download_zip(self, destination_directory: str):
56-
# Define the directory and file path
57-
os.makedirs(destination_directory, exist_ok=True)
58-
file_path = os.path.join(destination_directory, f"{self.name}.zip")
59-
60-
# Download the file
61-
r = requests.get(self.download_url, allow_redirects=True)
62-
63-
# Raise an exception in case of http errors
64-
r.raise_for_status()
65-
66-
# Save the content to the specified file
67-
with open(file_path, "wb") as file:
68-
file.write(r.content)
69-
70-
return file_path
71-
7263
def __parse_release(self, json_payload: dict):
7364
if self.name is None:
7465
self.name = json_payload["name"]
@@ -77,6 +68,41 @@ def __parse_release(self, json_payload: dict):
7768
self.prerelease = json_payload["prerelease"]
7869
self.html_url = json_payload["html_url"]
7970

71+
self.__parse_release_assets(json_payload["assets_url"])
72+
73+
def __parse_release_assets(self, assets_url: str):
74+
75+
# Load assets
76+
r = requests.get(assets_url)
77+
78+
# Raise an exception in case of http errors
79+
r.raise_for_status()
80+
81+
json_assets = r.json()
82+
for json_asset in json_assets:
83+
84+
asset = ModuleVersion.Asset(
85+
name=json_asset["name"],
86+
download_url=json_asset["browser_download_url"],
87+
size=json_asset["size"],
88+
)
89+
90+
if asset.name == "datamodel.zip":
91+
self.asset_datamodel = asset
92+
continue
93+
94+
if asset.name == "project-translations.zip":
95+
self.asset_project = asset
96+
continue
97+
98+
if asset.name == "plugin.zip":
99+
self.asset_plugin = asset
100+
continue
101+
102+
if self.asset_datamodel and self.asset_project and self.asset_plugin:
103+
# We already have all assets we need
104+
break
105+
80106
def __parse_pull_request(self, json_payload: dict):
81107
if self.name is None:
82108
self.name = f"#{json_payload['number']} {json_payload['title']}"

oqtopus/core/package_prepare_task.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import requests
66
from qgis.PyQt.QtCore import QThread, pyqtSignal
77

8-
from ..utils.plugin_utils import PluginUtils
8+
from ..utils.plugin_utils import PluginUtils, logger
99

1010

1111
class PackagePrepareTask(QThread):
@@ -86,7 +86,7 @@ def __download_module_version(self, module_version):
8686

8787
self.__checkForCanceled()
8888

89-
# logging.info(f"Downloading from '{url}' to '{self.zip_file}'")
89+
logger.info(f"Downloading from '{url}' to '{self.zip_file}'")
9090
data_size = 0
9191
with open(self.zip_file, "wb") as file:
9292
next_emit_threshold = 10 * 1024 * 1024 # 10MB threshold

oqtopus/gui/main_dialog.py

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,29 @@
2222
#
2323
# ---------------------------------------------------------------------
2424

25-
import logging
2625
import os
2726
import shutil
2827

2928
import psycopg
3029
from qgis.PyQt.QtCore import Qt, QUrl
3130
from qgis.PyQt.QtGui import QColor, QDesktopServices
32-
from qgis.PyQt.QtWidgets import QAction, QDialog, QFileDialog, QMenu, QMessageBox
31+
from qgis.PyQt.QtWidgets import (
32+
QAction,
33+
QApplication,
34+
QDialog,
35+
QFileDialog,
36+
QMenu,
37+
QMessageBox,
38+
QStyle,
39+
QTreeWidgetItem,
40+
)
3341

3442
from ..core.package_prepare_task import PackagePrepareTask
3543
from ..libs import pgserviceparser
3644
from ..libs.pum.config import PumConfig
3745
from ..libs.pum.schema_migrations import SchemaMigrations
3846
from ..libs.pum.upgrader import Upgrader
39-
from ..utils.plugin_utils import LoggingBridge, PluginUtils
47+
from ..utils.plugin_utils import LoggingBridge, PluginUtils, logger
4048
from ..utils.qt_utils import OverrideCursor, QtUtils
4149
from .database_create_dialog import DatabaseCreateDialog
4250
from .database_duplicate_dialog import DatabaseDuplicateDialog
@@ -56,10 +64,9 @@ def __init__(self, modules_registry, parent=None):
5664
QDialog.__init__(self, parent)
5765
self.setupUi(self)
5866

59-
self.logger = logging.getLogger()
6067
self.loggingBridge = LoggingBridge()
6168
self.loggingBridge.loggedLine.connect(self.__logged_line)
62-
self.logger.addHandler(self.loggingBridge)
69+
logger.addHandler(self.loggingBridge)
6370

6471
self.buttonBox.rejected.connect(self.__closeDialog)
6572
self.buttonBox.helpRequested.connect(self.__helpRequested)
@@ -86,13 +93,16 @@ def __init__(self, modules_registry, parent=None):
8693
# Init GUI Project
8794
self.__initGuiProject()
8895

96+
# Init GUI Logs
97+
self.__initGuiLogs()
98+
8999
self.__packagePrepareTask = PackagePrepareTask(self)
90100
self.__packagePrepareTask.finished.connect(self.__packagePrepareTaskFinished)
91101
self.__packagePrepareTask.signalPackagingProgress.connect(
92102
self.__packagePrepareTaskProgress
93103
)
94104

95-
self.logger.info("Ready.")
105+
logger.info("Ready.")
96106

97107
def __initGuiModules(self):
98108
self.module_module_comboBox.clear()
@@ -150,11 +160,29 @@ def __initGuiProject(self):
150160
self.project_install_pushButton.clicked.connect(self.__projectInstallClicked)
151161
self.project_seeChangelog_pushButton.clicked.connect(self.__projectSeeChangelogClicked)
152162

163+
def __initGuiLogs(self):
164+
self.logs_openFile_toolButton.setIcon(
165+
QApplication.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon)
166+
)
167+
self.logs_openFolder_toolButton.setIcon(
168+
QApplication.style().standardIcon(QStyle.StandardPixmap.SP_DirOpenIcon)
169+
)
170+
self.logs_clear_toolButton.setIcon(
171+
QApplication.style().standardIcon(QStyle.StandardPixmap.SP_TitleBarCloseButton)
172+
)
173+
174+
self.logs_openFile_toolButton.clicked.connect(self.__logsOpenFileClicked)
175+
self.logs_openFolder_toolButton.clicked.connect(self.__logsOpenFolderClicked)
176+
self.logs_clear_toolButton.clicked.connect(self.__logsClearClicked)
177+
153178
def __logged_line(self, record, line):
154-
self.logs_plainTextEdit.appendPlainText(line)
179+
180+
treeWidgetItem = QTreeWidgetItem([record.levelname, record.name, record.msg])
181+
182+
self.logs_treeWidget.addTopLevelItem(treeWidgetItem)
155183

156184
# Automatically scroll to the bottom of the logs
157-
scroll_bar = self.logs_plainTextEdit.verticalScrollBar()
185+
scroll_bar = self.logs_treeWidget.verticalScrollBar()
158186
scroll_bar.setValue(scroll_bar.maximum())
159187

160188
def __closeDialog(self):
@@ -166,7 +194,7 @@ def __closeDialog(self):
166194

167195
def __helpRequested(self):
168196
help_page = "https://github.com/oqtopus/Oqtopus"
169-
self.logger.info(f"Opening help page {help_page}")
197+
logger.info(f"Opening help page {help_page}")
170198
QDesktopServices.openUrl(QUrl(help_page))
171199

172200
def __loadDatabaseInformations(self):
@@ -198,6 +226,9 @@ def __moduleChanged(self, index):
198226
if self.__current_module is None:
199227
return
200228

229+
logger.info(f"Loading versions for module '{self.__current_module.name}'...")
230+
QApplication.processEvents()
231+
201232
with OverrideCursor(Qt.WaitCursor):
202233
if self.__current_module.versions == list():
203234
self.__current_module.load_versions()
@@ -249,7 +280,7 @@ def __moduleVersionChanged(self, index):
249280
)
250281
self.module_information_label.setText(loading_text)
251282
QtUtils.resetForegroundColor(self.module_information_label)
252-
self.logger.info(loading_text)
283+
logger.info(loading_text)
253284

254285
if self.__packagePrepareTask.isRunning():
255286
self.__packagePrepareTask.cancel()
@@ -312,7 +343,7 @@ def __loadModuleFromZip(self, filename):
312343
self.__packagePrepareTask.startFromZip(filename)
313344

314345
def __packagePrepareTaskFinished(self):
315-
self.logger.info("Load package task finished")
346+
logger.info("Load package task finished")
316347

317348
if self.__packagePrepareTask.lastError is not None:
318349
error_text = f"Can't load module package:\n{self.__packagePrepareTask.lastError}"
@@ -326,7 +357,7 @@ def __packagePrepareTaskFinished(self):
326357
return
327358

328359
self.__package_dir = self.__packagePrepareTask.package_dir
329-
self.logger.info(f"Package loaded into '{self.__package_dir}'")
360+
logger.info(f"Package loaded into '{self.__package_dir}'")
330361
self.module_information_label.setText(self.__package_dir)
331362
QtUtils.resetForegroundColor(self.module_information_label)
332363

@@ -417,7 +448,7 @@ def __packagePrepareGetProjectFilename(self):
417448

418449
def __packagePrepareTaskProgress(self, progress):
419450
loading_text = self.tr("Load package task running...")
420-
self.logger.info(loading_text)
451+
logger.info(loading_text)
421452
self.module_information_label.setText(loading_text)
422453

423454
def __seeChangeLogClicked(self):
@@ -448,7 +479,7 @@ def __seeChangeLogClicked(self):
448479
return
449480

450481
changelog_url = current_module_version.html_url
451-
self.logger.info(f"Opening changelog URL: {changelog_url}")
482+
logger.info(f"Opening changelog URL: {changelog_url}")
452483
QDesktopServices.openUrl(QUrl(changelog_url))
453484

454485
def __serviceChanged(self, index=None):
@@ -720,3 +751,12 @@ def __projectInstallClicked(self):
720751

721752
def __projectSeeChangelogClicked(self):
722753
self.__seeChangeLogClicked()
754+
755+
def __logsOpenFileClicked(self):
756+
QDesktopServices.openUrl(QUrl.fromLocalFile(PluginUtils.plugin_temp_path()))
757+
758+
def __logsOpenFolderClicked(self):
759+
PluginUtils.open_logs_folder()
760+
761+
def __logsClearClicked(self):
762+
self.logs_treeWidget.clear()

oqtopus/oqtopus_plugin.py

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
import logging
2-
import logging.handlers
3-
4-
from qgis.PyQt.QtCore import QDir, QFileInfo, QUrl
5-
from qgis.PyQt.QtGui import QDesktopServices, QIcon
1+
from qgis.PyQt.QtGui import QIcon
62
from qgis.PyQt.QtWidgets import QAction, QApplication
73

84
from .core.module import Module
95
from .core.modules_registry import ModulesRegistry
106
from .gui.about_dialog import AboutDialog
117
from .gui.main_dialog import MainDialog
12-
from .utils.plugin_utils import PluginUtils
8+
from .utils.plugin_utils import PluginUtils, logger
139

1410

1511
class OqtopusPlugin:
@@ -28,8 +24,10 @@ def __init__(self, iface):
2824

2925
self.__version__ = PluginUtils.get_plugin_version()
3026

31-
self.logsDirectory = f"{PluginUtils.plugin_root_path()}/logs"
32-
self._initLogger()
27+
PluginUtils.init_logger()
28+
29+
logger.info("")
30+
logger.info(f"Starting {PluginUtils.PLUGIN_NAME} plugin version {self.__version__}")
3331

3432
self.actions = []
3533
self.main_menu_name = self.tr(f"&{PluginUtils.PLUGIN_NAME}")
@@ -166,7 +164,7 @@ def show_main_dialog(self):
166164
main_dialog.exec_()
167165

168166
def show_logs_folder(self):
169-
QDesktopServices.openUrl(QUrl.fromLocalFile(self.logsDirectory))
167+
PluginUtils.open_logs_folder()
170168

171169
def show_about_dialog(self):
172170
about_dialog = AboutDialog(self.iface.mainWindow())
@@ -185,28 +183,3 @@ def _get_main_menu_action(self):
185183
]
186184

187185
return result_actions[0]
188-
189-
def _initLogger(self):
190-
directory = QDir(self.logsDirectory)
191-
if not directory.exists():
192-
directory.mkpath(self.logsDirectory)
193-
194-
if directory.exists():
195-
logfile = QFileInfo(directory, "Oqtopus.log")
196-
197-
# Handler for files rotation, create one log per day
198-
rotationHandler = logging.handlers.TimedRotatingFileHandler(
199-
logfile.filePath(), when="midnight", backupCount=10
200-
)
201-
202-
# Configure logging
203-
logging.basicConfig(
204-
level=logging.DEBUG,
205-
format="%(asctime)s %(levelname)-7s %(message)s",
206-
handlers=[rotationHandler],
207-
)
208-
else:
209-
logging.error(f"Can't create log files directory '{self.logsDirectory}'.")
210-
211-
logging.info("")
212-
logging.info(f"Starting {PluginUtils.PLUGIN_NAME} plugin version {self.__version__}")

0 commit comments

Comments
 (0)