oqtopus 0.1.17__py3-none-any.whl → 0.1.19__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
oqtopus/core/module.py CHANGED
@@ -3,7 +3,7 @@ import json
3
3
  from qgis.PyQt.QtCore import QByteArray, QObject, QUrl, pyqtSignal
4
4
  from qgis.PyQt.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
5
5
 
6
- from ..utils.plugin_utils import PluginUtils
6
+ from ..utils.plugin_utils import PluginUtils, logger
7
7
  from .module_package import ModulePackage
8
8
 
9
9
 
@@ -25,8 +25,9 @@ class Module(QObject):
25
25
  return f"Module(name={self.name}, organisation={self.organisation}, repository={self.repository})"
26
26
 
27
27
  def start_load_versions(self):
28
- url = QUrl(f"https://api.github.com/repos/{self.organisation}/{self.repository}/releases")
29
- request = QNetworkRequest(url)
28
+ url = f"https://api.github.com/repos/{self.organisation}/{self.repository}/releases"
29
+ logger.info(f"Loading versions from '{url}'...")
30
+ request = QNetworkRequest(QUrl(url))
30
31
  headers = PluginUtils.get_github_headers()
31
32
  for key, value in headers.items():
32
33
  request.setRawHeader(QByteArray(key.encode()), QByteArray(value.encode()))
@@ -83,8 +84,10 @@ class Module(QObject):
83
84
  )
84
85
  self.development_versions.append(mainVersion)
85
86
 
86
- url = QUrl(f"https://api.github.com/repos/{self.organisation}/{self.repository}/pulls")
87
- request = QNetworkRequest(url)
87
+ url = f"https://api.github.com/repos/{self.organisation}/{self.repository}/pulls"
88
+ logger.info(f"Loading development versions from '{url}'...")
89
+
90
+ request = QNetworkRequest(QUrl(url))
88
91
  headers = PluginUtils.get_github_headers()
89
92
  for key, value in headers.items():
90
93
  request.setRawHeader(QByteArray(key.encode()), QByteArray(value.encode()))
@@ -14,3 +14,5 @@ class ModuleAsset:
14
14
  self.download_url = download_url
15
15
  self.size = size
16
16
  self.type = type
17
+ self.package_zip = None
18
+ self.package_dir = None
@@ -25,6 +25,8 @@ class ModulePackage:
25
25
  branch=None,
26
26
  ):
27
27
  self.module = module
28
+ self.organisation = organisation
29
+ self.repository = repository
28
30
  self.type = type
29
31
  self.name = name
30
32
  self.branch = branch
@@ -50,12 +52,10 @@ class ModulePackage:
50
52
  if self.type == ModulePackage.Type.RELEASE:
51
53
  type = "tags"
52
54
 
53
- self.download_url = (
54
- f"https://github.com/{organisation}/{repository}/archive/refs/{type}/{self.branch}.zip"
55
- )
55
+ self.download_url = f"https://github.com/{self.organisation}/{self.repository}/archive/refs/{type}/{self.branch}.zip"
56
56
 
57
- self.zip_file = None
58
- self.package_dir = None
57
+ self.source_package_zip = None
58
+ self.source_package_dir = None
59
59
 
60
60
  def display_name(self):
61
61
  if self.prerelease:
@@ -116,3 +116,8 @@ class ModulePackage:
116
116
  self.created_at = QDateTime.fromString(json_payload["created_at"], Qt.DateFormat.ISODate)
117
117
  self.prerelease = False
118
118
  self.html_url = json_payload["html_url"]
119
+
120
+ is_on_a_fork = json_payload["head"]["repo"]["fork"]
121
+ if is_on_a_fork:
122
+ self.organisation = json_payload["head"]["repo"]["owner"]["login"]
123
+ self.repository = json_payload["head"]["repo"]["name"]
@@ -25,6 +25,8 @@ class PackagePrepareTask(QThread):
25
25
 
26
26
  self.module_package = None
27
27
 
28
+ self.__destination_directory = None
29
+
28
30
  self.__canceled = False
29
31
  self.lastError = None
30
32
 
@@ -53,6 +55,8 @@ class PackagePrepareTask(QThread):
53
55
  if self.module_package is None:
54
56
  raise Exception(self.tr("No module version provided."))
55
57
 
58
+ self.__destination_directory = self.__prepareDestinationDirectory()
59
+
56
60
  self.__download_module_assets(self.module_package)
57
61
  self.lastError = None
58
62
 
@@ -61,13 +65,29 @@ class PackagePrepareTask(QThread):
61
65
  logger.critical(f"Package prepare task error: {e}")
62
66
  self.lastError = e
63
67
 
68
+ def __prepareDestinationDirectory(self):
69
+ """
70
+ Prepare the destination directory for the module package.
71
+ This method creates a temporary directory for the package.
72
+ """
73
+ temp_dir = PluginUtils.plugin_temp_path()
74
+ destination_directory = os.path.join(
75
+ temp_dir,
76
+ self.module_package.organisation,
77
+ self.module_package.repository,
78
+ self.module_package.name,
79
+ )
80
+ os.makedirs(destination_directory, exist_ok=True)
81
+
82
+ return destination_directory
83
+
64
84
  def __download_module_assets(self, module_package):
65
85
 
66
86
  # Download the source
67
87
  zip_file = self.__download_module_asset(module_package.download_url, "source.zip")
68
- module_package.zip_file = zip_file
88
+ module_package.source_package_zip = zip_file
69
89
  package_dir = self.__extract_zip_file(zip_file)
70
- module_package.package_dir = package_dir
90
+ module_package.source_package_dir = package_dir
71
91
 
72
92
  # Download the release assets
73
93
  self.__checkForCanceled()
@@ -77,6 +97,7 @@ class PackagePrepareTask(QThread):
77
97
  module_package.asset_project.type.value + ".zip",
78
98
  )
79
99
  package_dir = self.__extract_zip_file(zip_file)
100
+ module_package.asset_project.package_zip = zip_file
80
101
  module_package.asset_project.package_dir = package_dir
81
102
 
82
103
  self.__checkForCanceled()
@@ -86,15 +107,12 @@ class PackagePrepareTask(QThread):
86
107
  module_package.asset_plugin.type.value + ".zip",
87
108
  )
88
109
  package_dir = self.__extract_zip_file(zip_file)
110
+ module_package.asset_plugin.package_zip = zip_file
89
111
  module_package.asset_plugin.package_dir = package_dir
90
112
 
91
113
  def __download_module_asset(self, url: str, filename: str):
92
114
 
93
- temp_dir = PluginUtils.plugin_temp_path()
94
- destination_directory = os.path.join(temp_dir, "Downloads")
95
- os.makedirs(destination_directory, exist_ok=True)
96
-
97
- zip_file = os.path.join(destination_directory, filename)
115
+ zip_file = os.path.join(self.__destination_directory, filename)
98
116
 
99
117
  # Streaming, so we can iterate over the response.
100
118
  response = requests.get(url, allow_redirects=True, stream=True)
@@ -121,19 +139,17 @@ class PackagePrepareTask(QThread):
121
139
  return zip_file
122
140
 
123
141
  def __extract_zip_file(self, zip_file):
124
- temp_dir = PluginUtils.plugin_temp_path()
125
-
126
142
  # Unzip the file to plugin temp dir
127
143
  try:
128
144
  with zipfile.ZipFile(zip_file, "r") as zip_ref:
129
145
  # Find the top-level directory
130
146
  zip_dirname = zip_ref.namelist()[0].split("/")[0]
131
- package_dir = os.path.join(temp_dir, zip_dirname)
147
+ package_dir = os.path.join(self.__destination_directory, zip_dirname)
132
148
 
133
149
  if os.path.exists(package_dir):
134
150
  shutil.rmtree(package_dir)
135
151
 
136
- zip_ref.extractall(temp_dir)
152
+ zip_ref.extractall(self.__destination_directory)
137
153
 
138
154
  except zipfile.BadZipFile:
139
155
  raise Exception(self.tr(f"The selected file '{zip_file}' is not a valid zip archive."))
@@ -60,6 +60,15 @@ class DatabaseConnectionWidget(QWidget, DIALOG_UI):
60
60
  """
61
61
  return self.__database_connection
62
62
 
63
+ def getService(self):
64
+ """
65
+ Returns the current service name.
66
+ If no service is selected, returns None.
67
+ """
68
+ if self.db_services_comboBox.currentText() == "":
69
+ return None
70
+ return self.db_services_comboBox.currentText()
71
+
63
72
  def __loadDatabaseInformations(self):
64
73
  pg_service_conf_path = pgserviceparser_conf_path()
65
74
  self.db_servicesConfigFilePath_label.setText(
@@ -62,6 +62,11 @@ class LogModel(QAbstractItemModel):
62
62
  | Qt.ItemFlag.ItemNeverHasChildren
63
63
  )
64
64
 
65
+ def clear(self):
66
+ self.beginResetModel()
67
+ self.logs = []
68
+ self.endResetModel()
69
+
65
70
 
66
71
  class LogFilterProxyModel(QSortFilterProxyModel):
67
72
  LEVELS = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
@@ -45,6 +45,7 @@ from .database_connection_widget import DatabaseConnectionWidget # noqa: E402
45
45
  from .logs_widget import LogsWidget # noqa: E402
46
46
  from .module_selection_widget import ModuleSelectionWidget # noqa: E402
47
47
  from .module_widget import ModuleWidget # noqa: E402
48
+ from .plugin_widget import PluginWidget # noqa: E402
48
49
  from .project_widget import ProjectWidget # noqa: E402
49
50
 
50
51
  DIALOG_UI = PluginUtils.get_ui_class("main_dialog.ui")
@@ -52,7 +53,7 @@ DIALOG_UI = PluginUtils.get_ui_class("main_dialog.ui")
52
53
 
53
54
  class MainDialog(QDialog, DIALOG_UI):
54
55
 
55
- def __init__(self, modules_config, parent=None):
56
+ def __init__(self, modules_config_path, parent=None):
56
57
  QDialog.__init__(self, parent)
57
58
  self.setupUi(self)
58
59
 
@@ -60,7 +61,7 @@ class MainDialog(QDialog, DIALOG_UI):
60
61
  self.buttonBox.helpRequested.connect(self.__helpRequested)
61
62
 
62
63
  # Init GUI Modules
63
- self.__moduleSelectionWidget = ModuleSelectionWidget(modules_config, self)
64
+ self.__moduleSelectionWidget = ModuleSelectionWidget(modules_config_path, self)
64
65
  self.moduleSelection_groupBox.layout().addWidget(self.__moduleSelectionWidget)
65
66
 
66
67
  # Init GUI Database
@@ -75,6 +76,10 @@ class MainDialog(QDialog, DIALOG_UI):
75
76
  self.__projectWidget = ProjectWidget(self)
76
77
  self.project_tab.layout().addWidget(self.__projectWidget)
77
78
 
79
+ # Init GUI Plugin
80
+ self.__pluginWidget = PluginWidget(self)
81
+ self.plugin_tab.layout().addWidget(self.__pluginWidget)
82
+
78
83
  # Init GUI Logs
79
84
  self.__logsWidget = LogsWidget(self)
80
85
  self.logs_groupBox.layout().addWidget(self.__logsWidget)
@@ -108,6 +113,7 @@ class MainDialog(QDialog, DIALOG_UI):
108
113
  self.__databaseConnectionWidget.signal_connectionChanged.connect(
109
114
  self.__databaseConnectionWidget_connectionChanged
110
115
  )
116
+ self.__databaseConnectionWidget_connectionChanged()
111
117
 
112
118
  self.module_tab.setEnabled(False)
113
119
  self.plugin_tab.setEnabled(False)
@@ -164,5 +170,11 @@ class MainDialog(QDialog, DIALOG_UI):
164
170
  self.__moduleSelectionWidget.getSelectedModulePackage()
165
171
  )
166
172
 
173
+ self.__pluginWidget.setModulePackage(
174
+ self.__moduleSelectionWidget.getSelectedModulePackage()
175
+ )
176
+
167
177
  def __databaseConnectionWidget_connectionChanged(self):
168
178
  self.__moduleWidget.setDatabaseConnection(self.__databaseConnectionWidget.getConnection())
179
+
180
+ self.__projectWidget.setService(self.__databaseConnectionWidget.getService())
@@ -1,9 +1,11 @@
1
+ import yaml
1
2
  from qgis.PyQt.QtCore import Qt, QUrl, pyqtSignal
2
3
  from qgis.PyQt.QtGui import QDesktopServices
3
4
  from qgis.PyQt.QtWidgets import QApplication, QFileDialog, QMessageBox, QWidget
4
5
 
5
6
  from ..core.module import Module
6
7
  from ..core.module_package import ModulePackage
8
+ from ..core.modules_config import ModulesConfig
7
9
  from ..core.package_prepare_task import PackagePrepareTask, PackagePrepareTaskCanceled
8
10
  from ..utils.plugin_utils import PluginUtils, logger
9
11
  from ..utils.qt_utils import CriticalMessageBox, OverrideCursor, QtUtils
@@ -18,28 +20,44 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
18
20
  signal_loadingStarted = pyqtSignal()
19
21
  signal_loadingFinished = pyqtSignal()
20
22
 
21
- def __init__(self, modules_config, parent=None):
23
+ def __init__(self, modules_config_path, parent=None):
22
24
  QWidget.__init__(self, parent)
23
25
  self.setupUi(self)
24
26
 
25
27
  self.__current_module = None
26
28
  self.__current_module_package = None
27
- self.__modules_config = modules_config
29
+ self.__modules_config = None
30
+
31
+ try:
32
+ with modules_config_path.open() as f:
33
+ data = yaml.safe_load(f)
34
+ self.__modules_config = ModulesConfig(**data)
35
+ except Exception as e:
36
+ logger.error(f"Error loading modules config from {modules_config_path}: {e}")
37
+ QMessageBox.critical(
38
+ self,
39
+ self.tr("Error"),
40
+ self.tr(f"Can't load modules configuration from '{modules_config_path}': {e}"),
41
+ )
42
+ self.__modules_config = None
28
43
 
29
44
  self.module_progressBar.setVisible(False)
30
45
 
31
46
  self.module_module_comboBox.clear()
32
47
  self.module_module_comboBox.addItem(self.tr("Please select a module"), None)
33
- for config_module in self.__modules_config.modules:
34
- module = Module(
35
- name=config_module.name,
36
- organisation=config_module.organisation,
37
- repository=config_module.repository,
38
- parent=self,
39
- )
40
- self.module_module_comboBox.addItem(module.name, module)
41
- module.signal_versionsLoaded.connect(self.__loadVersionsFinished)
42
- module.signal_developmentVersionsLoaded.connect(self.__loadDevelopmentVersionsFinished)
48
+ if self.__modules_config is not None:
49
+ for config_module in self.__modules_config.modules:
50
+ module = Module(
51
+ name=config_module.name,
52
+ organisation=config_module.organisation,
53
+ repository=config_module.repository,
54
+ parent=self,
55
+ )
56
+ self.module_module_comboBox.addItem(module.name, module)
57
+ module.signal_versionsLoaded.connect(self.__loadVersionsFinished)
58
+ module.signal_developmentVersionsLoaded.connect(
59
+ self.__loadDevelopmentVersionsFinished
60
+ )
43
61
 
44
62
  self.module_latestVersion_label.setText("")
45
63
  QtUtils.setForegroundColor(self.module_latestVersion_label, PluginUtils.COLOR_GREEN)
@@ -190,20 +208,26 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
190
208
  QtUtils.setForegroundColor(self.module_information_label, PluginUtils.COLOR_WARNING)
191
209
  return
192
210
 
193
- package_dir = self.module_package_comboBox.currentData().package_dir
211
+ package_dir = self.module_package_comboBox.currentData().source_package_dir
194
212
  logger.info(f"Package loaded into '{package_dir}'")
195
- self.module_information_label.setText(package_dir)
196
213
  QtUtils.resetForegroundColor(self.module_information_label)
214
+ self.module_information_label.setText(
215
+ f"<a href='file://{package_dir}'>{package_dir}</a>",
216
+ )
197
217
 
198
218
  asset_project = self.module_package_comboBox.currentData().asset_project
199
219
  if asset_project:
200
- self.module_informationProject_label.setText(asset_project.package_dir)
220
+ self.module_informationProject_label.setText(
221
+ f"<a href='file://{asset_project.package_dir}'>{asset_project.package_dir}</a>",
222
+ )
201
223
  else:
202
224
  self.module_informationProject_label.setText("No asset available")
203
225
 
204
226
  asset_plugin = self.module_package_comboBox.currentData().asset_plugin
205
227
  if asset_plugin:
206
- self.module_informationPlugin_label.setText(asset_plugin.package_dir)
228
+ self.module_informationPlugin_label.setText(
229
+ f"<a href='file://{asset_plugin.package_dir}'>{asset_plugin.package_dir}</a>",
230
+ )
207
231
  else:
208
232
  self.module_informationPlugin_label.setText("No asset available")
209
233
 
@@ -8,6 +8,7 @@ from qgis.PyQt.QtCore import Qt
8
8
  from qgis.PyQt.QtWidgets import QMessageBox, QWidget
9
9
 
10
10
  from ..core.module import Module
11
+ from ..core.module_package import ModulePackage
11
12
  from ..utils.plugin_utils import PluginUtils, logger
12
13
  from ..utils.qt_utils import CriticalMessageBox, OverrideCursor, QtUtils
13
14
 
@@ -42,13 +43,13 @@ class ModuleWidget(QWidget, DIALOG_UI):
42
43
  self.__updateModuleInfo()
43
44
 
44
45
  def __packagePrepareGetPUMConfig(self):
45
- package_dir = self.__current_module_package.package_dir
46
+ package_dir = self.__current_module_package.source_package_dir
46
47
 
47
48
  if package_dir is None:
48
49
  CriticalMessageBox(
49
50
  self.tr("Error"),
50
51
  self.tr(
51
- f"The selected file '{self.__current_module_package.zip_file}' does not contain a valid package directory."
52
+ f"The selected file '{self.__current_module_package.source_package_zip}' does not contain a valid package directory."
52
53
  ),
53
54
  None,
54
55
  self,
@@ -61,7 +62,7 @@ class ModuleWidget(QWidget, DIALOG_UI):
61
62
  CriticalMessageBox(
62
63
  self.tr("Error"),
63
64
  self.tr(
64
- f"The selected file '{self.__current_module_package.zip_file}' does not contain a valid .pum.yaml file."
65
+ f"The selected file '{self.__current_module_package.source_package_zip}' does not contain a valid .pum.yaml file."
65
66
  ),
66
67
  None,
67
68
  self,
@@ -81,7 +82,16 @@ class ModuleWidget(QWidget, DIALOG_UI):
81
82
 
82
83
  logger.info(f"PUM config loaded from '{pumConfigFilename}'")
83
84
 
84
- self.parameters_groupbox.setParameters(self.__pum_config.parameters())
85
+ try:
86
+ self.parameters_groupbox.setParameters(self.__pum_config.parameters())
87
+ except Exception as exception:
88
+ CriticalMessageBox(
89
+ self.tr("Error"),
90
+ self.tr(f"Can't load parameters from PUM config '{pumConfigFilename}':"),
91
+ exception,
92
+ self,
93
+ ).exec()
94
+ return
85
95
 
86
96
  self.db_demoData_comboBox.clear()
87
97
  for demo_data_name, demo_data_file in self.__pum_config.demo_data().items():
@@ -107,9 +117,19 @@ class ModuleWidget(QWidget, DIALOG_UI):
107
117
  ).exec()
108
118
  return
109
119
 
110
- parameters = self.parameters_groupbox.parameters_values()
111
-
112
120
  try:
121
+ parameters = self.parameters_groupbox.parameters_values()
122
+
123
+ beta_testing = False
124
+ if (
125
+ self.__current_module_package.type == ModulePackage.Type.PULL_REQUEST
126
+ or self.__current_module_package.type == ModulePackage.Type.BRANCH
127
+ ):
128
+ logger.warning(
129
+ "Installing module from branch or pull request: set parameter beta_testing to True"
130
+ )
131
+ beta_testing = True
132
+
113
133
  upgrader = Upgrader(
114
134
  config=self.__pum_config,
115
135
  )
@@ -119,6 +139,7 @@ class ModuleWidget(QWidget, DIALOG_UI):
119
139
  connection=self.__database_connection,
120
140
  roles=self.db_parameters_CreateAndGrantRoles_checkBox.isChecked(),
121
141
  grant=self.db_parameters_CreateAndGrantRoles_checkBox.isChecked(),
142
+ beta_testing=beta_testing,
122
143
  )
123
144
 
124
145
  if self.db_demoData_checkBox.isChecked():
@@ -20,21 +20,21 @@ class ParameterWidget(QWidget):
20
20
  self.layout.setContentsMargins(0, 0, 0, 0)
21
21
  self.setLayout(self.layout)
22
22
  self.value = None
23
- self.__valueChanged = False
24
23
 
25
24
  if parameter_definition.type != ParameterType.BOOLEAN:
26
25
  self.layout.addWidget(QLabel(parameter_definition.name, self))
27
26
 
28
27
  if parameter_definition.type == ParameterType.BOOLEAN:
29
28
  self.widget = QCheckBox(parameter_definition.name, self)
30
- self.widget.setChecked(parameter_definition.default)
31
- self.widget.checked.connect(self.__valueChanged)
29
+ if parameter_definition.default is not None:
30
+ self.widget.setChecked(parameter_definition.default)
32
31
  self.layout.addWidget(self.widget)
33
32
  self.value = lambda: self.widget.isChecked()
34
33
  elif parameter_definition.type in (
35
34
  ParameterType.DECIMAL,
36
35
  ParameterType.INTEGER,
37
36
  ParameterType.TEXT,
37
+ ParameterType.PATH,
38
38
  ):
39
39
  self.widget = QLineEdit(self)
40
40
  if parameter_definition.default is not None:
@@ -46,6 +46,8 @@ class ParameterWidget(QWidget):
46
46
  self.value = lambda: float(self.widget.text() or self.widget.placeholderText())
47
47
  else:
48
48
  self.value = lambda: self.widget.text() or self.widget.placeholderText()
49
+ else:
50
+ raise ValueError(f"Unknown parameter type '{parameter_definition.type}'")
49
51
 
50
52
 
51
53
  class ParametersGroupBox(QGroupBox):
@@ -0,0 +1,157 @@
1
+ import os
2
+ import shutil
3
+
4
+ from qgis.PyQt.QtCore import QUrl
5
+ from qgis.PyQt.QtGui import QDesktopServices
6
+ from qgis.PyQt.QtWidgets import QFileDialog, QMessageBox, QWidget
7
+
8
+ from ..core.module_package import ModulePackage
9
+ from ..utils.plugin_utils import PluginUtils, logger
10
+ from ..utils.qt_utils import QtUtils
11
+
12
+ DIALOG_UI = PluginUtils.get_ui_class("plugin_widget.ui")
13
+
14
+
15
+ class PluginWidget(QWidget, DIALOG_UI):
16
+
17
+ def __init__(self, parent=None):
18
+ QWidget.__init__(self, parent)
19
+ self.setupUi(self)
20
+
21
+ self.install_pushButton.clicked.connect(self.__installClicked)
22
+ self.seeChangelog_pushButton.clicked.connect(self.__seeChangelogClicked)
23
+ self.copyZipToDirectory_pushButton.clicked.connect(self.__copyZipToDirectoryClicked)
24
+
25
+ self.__current_module_package = None
26
+
27
+ def setModulePackage(self, module_package: ModulePackage):
28
+ self.__current_module_package = module_package
29
+ self.__packagePrepareGetPluginFilename()
30
+
31
+ def __packagePrepareGetPluginFilename(self):
32
+ asset_plugin = self.__current_module_package.asset_plugin
33
+ if asset_plugin is None:
34
+ self.info_label.setText(self.tr("No plugin asset available for this module version."))
35
+ QtUtils.setForegroundColor(self.info_label, PluginUtils.COLOR_WARNING)
36
+ QtUtils.setFontItalic(self.info_label, True)
37
+ return
38
+
39
+ # Check if the package exists
40
+ if not os.path.exists(asset_plugin.package_zip):
41
+ self.info_label.setText(
42
+ self.tr(f"Plugin zip file '{asset_plugin.package_zip}' does not exist.")
43
+ )
44
+ QtUtils.setForegroundColor(self.info_label, PluginUtils.COLOR_WARNING)
45
+ QtUtils.setFontItalic(self.info_label, True)
46
+ return
47
+
48
+ QtUtils.resetForegroundColor(self.info_label)
49
+ QtUtils.setFontItalic(self.info_label, False)
50
+ self.info_label.setText(
51
+ f"<a href='file://{asset_plugin.package_zip}'>{asset_plugin.package_zip}</a>",
52
+ )
53
+
54
+ def __installClicked(self):
55
+ if self.__current_module_package is None:
56
+ QMessageBox.warning(
57
+ self,
58
+ self.tr("Error"),
59
+ self.tr("Please select a module and version first."),
60
+ )
61
+ return
62
+
63
+ # Check if the package exists
64
+ asset_plugin = self.__current_module_package.asset_plugin
65
+ if not os.path.exists(asset_plugin.package_zip):
66
+ self.info_label.setText(
67
+ self.tr(f"Plugin zip file '{asset_plugin.package_zip}' does not exist.")
68
+ )
69
+ QtUtils.setForegroundColor(self.info_label, PluginUtils.COLOR_WARNING)
70
+ QtUtils.setFontItalic(self.info_label, True)
71
+ return
72
+
73
+ QMessageBox.warning(
74
+ self,
75
+ self.tr("Not implemented"),
76
+ self.tr(
77
+ 'Installation is not implemented yet.\nAt the moment, you can only copy the plugin zip file to a directory and use "Install from ZIP" in QGIS.'
78
+ ),
79
+ )
80
+ return
81
+
82
+ def __seeChangelogClicked(self):
83
+ if self.__current_module_package is None:
84
+ QMessageBox.warning(
85
+ self,
86
+ self.tr("Can't open changelog"),
87
+ self.tr("Please select a module and version first."),
88
+ )
89
+ return
90
+
91
+ if self.__current_module_package.type == ModulePackage.Type.FROM_ZIP:
92
+ QMessageBox.warning(
93
+ self,
94
+ self.tr("Can't open changelog"),
95
+ self.tr("Changelog is not available for Zip packages."),
96
+ )
97
+ return
98
+
99
+ if self.__current_module_package.html_url is None:
100
+ QMessageBox.warning(
101
+ self,
102
+ self.tr("Can't open changelog"),
103
+ self.tr(
104
+ f"Changelog not available for version '{self.__current_module_package.display_name()}'."
105
+ ),
106
+ )
107
+ return
108
+
109
+ changelog_url = self.__current_module_package.html_url
110
+ logger.info(f"Opening changelog URL: {changelog_url}")
111
+ QDesktopServices.openUrl(QUrl(changelog_url))
112
+
113
+ def __copyZipToDirectoryClicked(self):
114
+ if self.__current_module_package is None:
115
+ QMessageBox.warning(
116
+ self,
117
+ self.tr("Error"),
118
+ self.tr("Please select a module and version first."),
119
+ )
120
+ return
121
+
122
+ # Check if the package exists
123
+ asset_plugin = self.__current_module_package.asset_plugin
124
+ if not os.path.exists(asset_plugin.package_zip):
125
+ self.info_label.setText(
126
+ self.tr(f"Plugin zip file '{asset_plugin.package_zip}' does not exist.")
127
+ )
128
+ QtUtils.setForegroundColor(self.info_label, PluginUtils.COLOR_WARNING)
129
+ QtUtils.setFontItalic(self.info_label, True)
130
+ return
131
+
132
+ install_destination = QFileDialog.getExistingDirectory(
133
+ self,
134
+ self.tr("Select installation directory"),
135
+ "",
136
+ QFileDialog.Option.ShowDirsOnly,
137
+ )
138
+
139
+ if not install_destination:
140
+ return
141
+
142
+ # Copy the plugin package to the selected directory
143
+ try:
144
+ shutil.copy2(asset_plugin.package_zip, install_destination)
145
+
146
+ QMessageBox.information(
147
+ self,
148
+ self.tr("Plugin copied"),
149
+ self.tr(f"Plugin package has been copied to '{install_destination}'."),
150
+ )
151
+ except Exception as e:
152
+ QMessageBox.critical(
153
+ self,
154
+ self.tr("Error"),
155
+ self.tr(f"Failed to copy plugin package: {e}"),
156
+ )
157
+ return
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import re
2
3
  import shutil
3
4
 
4
5
  from qgis.PyQt.QtCore import QUrl
@@ -22,11 +23,15 @@ class ProjectWidget(QWidget, DIALOG_UI):
22
23
  self.project_seeChangelog_pushButton.clicked.connect(self.__projectSeeChangelogClicked)
23
24
 
24
25
  self.__current_module_package = None
26
+ self.__current_service = None
25
27
 
26
28
  def setModulePackage(self, module_package: ModulePackage):
27
29
  self.__current_module_package = module_package
28
30
  self.__packagePrepareGetProjectFilename()
29
31
 
32
+ def setService(self, service):
33
+ self.__current_service = service
34
+
30
35
  def __packagePrepareGetProjectFilename(self):
31
36
  asset_project = self.__current_module_package.asset_project
32
37
  if asset_project is None:
@@ -110,6 +115,24 @@ class ProjectWidget(QWidget, DIALOG_UI):
110
115
 
111
116
  if os.path.isdir(source_path):
112
117
  shutil.copytree(source_path, destination_path, dirs_exist_ok=True)
118
+
119
+ elif item.endswith(".qgs"):
120
+ with open(source_path) as original_project:
121
+ contents = original_project.read()
122
+
123
+ if self.__current_service is not None:
124
+ contents = re.sub(
125
+ r"service='[^']+'", f"service='{self.__current_service}'", contents
126
+ )
127
+ else:
128
+ logger.warning(
129
+ "No service set, skipping service replacement in project file."
130
+ )
131
+
132
+ installed_path = os.path.join(install_destination, item)
133
+ with open(installed_path, "w") as output_file:
134
+ output_file.write(contents)
135
+
113
136
  else:
114
137
  shutil.copy2(source_path, destination_path)
115
138
 
oqtopus/oqtopus.py CHANGED
@@ -2,8 +2,6 @@ import sys
2
2
  import types
3
3
  from pathlib import Path
4
4
 
5
- import yaml
6
-
7
5
  # Create fake qgis.PyQt modules that point to PyQt5 modules
8
6
  try:
9
7
  pyqt_core = __import__("PyQt6.QtCore", fromlist=[""])
@@ -38,7 +36,6 @@ sys.modules["qgis.PyQt.uic"] = pyqt_uic
38
36
 
39
37
  from qgis.PyQt.QtGui import QIcon # noqa: E402
40
38
 
41
- from .core.modules_config import ModulesConfig # noqa: E402
42
39
  from .gui.main_dialog import MainDialog # noqa: E402
43
40
  from .utils.plugin_utils import PluginUtils # noqa: E402
44
41
 
@@ -52,11 +49,7 @@ def main():
52
49
 
53
50
  conf_path = Path(__file__).parent / "default_config.yaml"
54
51
 
55
- with conf_path.open() as f:
56
- data = yaml.safe_load(f)
57
- modules_config = ModulesConfig(**data)
58
-
59
- dialog = MainDialog(modules_config)
52
+ dialog = MainDialog(modules_config_path=conf_path)
60
53
  dialog.setWindowIcon(icon)
61
54
  dialog.show()
62
55
 
oqtopus/oqtopus_plugin.py CHANGED
@@ -1,11 +1,8 @@
1
1
  from pathlib import Path
2
2
 
3
- import yaml
4
3
  from qgis.PyQt.QtGui import QIcon
5
4
  from qgis.PyQt.QtWidgets import QAction, QApplication
6
5
 
7
- from oqtopus.core.modules_config import ModulesConfig
8
-
9
6
  from .gui.about_dialog import AboutDialog
10
7
  from .gui.main_dialog import MainDialog
11
8
  from .utils.plugin_utils import PluginUtils, logger
@@ -35,12 +32,6 @@ class OqtopusPlugin:
35
32
  self.actions = []
36
33
  self.main_menu_name = self.tr(f"&{PluginUtils.PLUGIN_NAME}")
37
34
 
38
- conf_path = Path(__file__).parent / "default_config.yaml"
39
-
40
- with conf_path.open() as f:
41
- data = yaml.safe_load(f)
42
- self.modules_config = ModulesConfig(**data)
43
-
44
35
  # noinspection PyMethodMayBeStatic
45
36
  def tr(self, source_text):
46
37
  """
@@ -159,7 +150,9 @@ class OqtopusPlugin:
159
150
  self.iface.removeToolBarIcon(action)
160
151
 
161
152
  def show_main_dialog(self):
162
- main_dialog = MainDialog(self.modules_config, self.iface.mainWindow())
153
+ conf_path = Path(__file__).parent / "default_config.yaml"
154
+
155
+ main_dialog = MainDialog(modules_config_path=conf_path, parent=self.iface.mainWindow())
163
156
  main_dialog.exec()
164
157
 
165
158
  def show_logs_folder(self):
@@ -7,7 +7,7 @@
7
7
  <x>0</x>
8
8
  <y>0</y>
9
9
  <width>513</width>
10
- <height>540</height>
10
+ <height>542</height>
11
11
  </rect>
12
12
  </property>
13
13
  <property name="windowTitle">
@@ -64,6 +64,9 @@
64
64
  <layout class="QGridLayout" name="gridLayout_5">
65
65
  <item row="5" column="1">
66
66
  <widget class="QLineEdit" name="parameters_password_lineEdit">
67
+ <property name="echoMode">
68
+ <enum>QLineEdit::PasswordEchoOnEdit</enum>
69
+ </property>
67
70
  <property name="clearButtonEnabled">
68
71
  <bool>true</bool>
69
72
  </property>
oqtopus/ui/main_dialog.ui CHANGED
@@ -63,77 +63,7 @@
63
63
  <attribute name="title">
64
64
  <string>Plugin</string>
65
65
  </attribute>
66
- <layout class="QGridLayout" name="gridLayout_6">
67
- <item row="1" column="1">
68
- <widget class="QLabel" name="label_8">
69
- <property name="font">
70
- <font>
71
- <italic>true</italic>
72
- </font>
73
- </property>
74
- <property name="text">
75
- <string>no current version</string>
76
- </property>
77
- </widget>
78
- </item>
79
- <item row="2" column="0">
80
- <widget class="QPushButton" name="pushButton_5">
81
- <property name="text">
82
- <string>Install 1.6.3</string>
83
- </property>
84
- </widget>
85
- </item>
86
- <item row="0" column="0">
87
- <widget class="QLabel" name="label_6">
88
- <property name="text">
89
- <string>Current QGIS profile</string>
90
- </property>
91
- </widget>
92
- </item>
93
- <item row="1" column="0">
94
- <widget class="QLabel" name="label_5">
95
- <property name="text">
96
- <string>Current version</string>
97
- </property>
98
- </widget>
99
- </item>
100
- <item row="3" column="0">
101
- <widget class="QPushButton" name="pushButton_8">
102
- <property name="text">
103
- <string>Copy ZIP to directory</string>
104
- </property>
105
- </widget>
106
- </item>
107
- <item row="2" column="1">
108
- <widget class="QPushButton" name="pushButton_11">
109
- <property name="text">
110
- <string>See changelog</string>
111
- </property>
112
- </widget>
113
- </item>
114
- <item row="0" column="1">
115
- <widget class="QLabel" name="label_7">
116
- <property name="font">
117
- <font>
118
- <italic>true</italic>
119
- </font>
120
- </property>
121
- <property name="text">
122
- <string>tww_user_profile</string>
123
- </property>
124
- </widget>
125
- </item>
126
- <item row="4" column="0">
127
- <spacer name="verticalSpacer_6">
128
- <property name="sizeHint" stdset="0">
129
- <size>
130
- <width>20</width>
131
- <height>40</height>
132
- </size>
133
- </property>
134
- </spacer>
135
- </item>
136
- </layout>
66
+ <layout class="QGridLayout" name="gridLayout_6"/>
137
67
  </widget>
138
68
  </widget>
139
69
  </item>
@@ -26,6 +26,12 @@
26
26
  <property name="text">
27
27
  <string>-</string>
28
28
  </property>
29
+ <property name="openExternalLinks">
30
+ <bool>true</bool>
31
+ </property>
32
+ <property name="textInteractionFlags">
33
+ <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
34
+ </property>
29
35
  </widget>
30
36
  </item>
31
37
  <item row="0" column="0">
@@ -54,6 +60,12 @@
54
60
  <property name="text">
55
61
  <string>-</string>
56
62
  </property>
63
+ <property name="openExternalLinks">
64
+ <bool>true</bool>
65
+ </property>
66
+ <property name="textInteractionFlags">
67
+ <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
68
+ </property>
57
69
  </widget>
58
70
  </item>
59
71
  <item row="2" column="0" colspan="3">
@@ -111,8 +123,11 @@
111
123
  <property name="text">
112
124
  <string>-</string>
113
125
  </property>
126
+ <property name="openExternalLinks">
127
+ <bool>true</bool>
128
+ </property>
114
129
  <property name="textInteractionFlags">
115
- <set>Qt::NoTextInteraction</set>
130
+ <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
116
131
  </property>
117
132
  </widget>
118
133
  </item>
@@ -0,0 +1,96 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ui version="4.0">
3
+ <class>Form</class>
4
+ <widget class="QWidget" name="Form">
5
+ <property name="geometry">
6
+ <rect>
7
+ <x>0</x>
8
+ <y>0</y>
9
+ <width>400</width>
10
+ <height>300</height>
11
+ </rect>
12
+ </property>
13
+ <property name="windowTitle">
14
+ <string>Form</string>
15
+ </property>
16
+ <layout class="QGridLayout" name="gridLayout">
17
+ <item row="2" column="0">
18
+ <widget class="QPushButton" name="install_pushButton">
19
+ <property name="text">
20
+ <string>Install</string>
21
+ </property>
22
+ </widget>
23
+ </item>
24
+ <item row="0" column="0">
25
+ <widget class="QLabel" name="label">
26
+ <property name="text">
27
+ <string>Current QGIS profile</string>
28
+ </property>
29
+ </widget>
30
+ </item>
31
+ <item row="0" column="1">
32
+ <widget class="QLabel" name="qgisProfile_label">
33
+ <property name="text">
34
+ <string>-</string>
35
+ </property>
36
+ </widget>
37
+ </item>
38
+ <item row="1" column="1">
39
+ <widget class="QLabel" name="currentVersion_label">
40
+ <property name="text">
41
+ <string>no current version</string>
42
+ </property>
43
+ </widget>
44
+ </item>
45
+ <item row="2" column="1">
46
+ <widget class="QPushButton" name="seeChangelog_pushButton">
47
+ <property name="text">
48
+ <string>See changelog</string>
49
+ </property>
50
+ </widget>
51
+ </item>
52
+ <item row="5" column="0">
53
+ <spacer name="verticalSpacer">
54
+ <property name="orientation">
55
+ <enum>Qt::Vertical</enum>
56
+ </property>
57
+ <property name="sizeHint" stdset="0">
58
+ <size>
59
+ <width>20</width>
60
+ <height>133</height>
61
+ </size>
62
+ </property>
63
+ </spacer>
64
+ </item>
65
+ <item row="3" column="0">
66
+ <widget class="QPushButton" name="copyZipToDirectory_pushButton">
67
+ <property name="text">
68
+ <string>Copy ZIP to directory</string>
69
+ </property>
70
+ </widget>
71
+ </item>
72
+ <item row="1" column="0">
73
+ <widget class="QLabel" name="label_3">
74
+ <property name="text">
75
+ <string>Current version</string>
76
+ </property>
77
+ </widget>
78
+ </item>
79
+ <item row="4" column="0" colspan="2">
80
+ <widget class="QLabel" name="info_label">
81
+ <property name="text">
82
+ <string>-</string>
83
+ </property>
84
+ <property name="openExternalLinks">
85
+ <bool>true</bool>
86
+ </property>
87
+ <property name="textInteractionFlags">
88
+ <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
89
+ </property>
90
+ </widget>
91
+ </item>
92
+ </layout>
93
+ </widget>
94
+ <resources/>
95
+ <connections/>
96
+ </ui>
@@ -17,7 +17,7 @@
17
17
  <item row="0" column="0">
18
18
  <widget class="QPushButton" name="project_install_pushButton">
19
19
  <property name="text">
20
- <string>Install demo project</string>
20
+ <string>Install template project</string>
21
21
  </property>
22
22
  </widget>
23
23
  </item>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oqtopus
3
- Version: 0.1.17
3
+ Version: 0.1.19
4
4
  Summary: A QGIS module manager
5
5
  Author-email: Damiano Lombardi <damiano@opengis.ch>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -0,0 +1,45 @@
1
+ oqtopus/__init__.py,sha256=PUl5ObSgoyF6tcNphBip9Rff8lul0t9VobiwsLKwgFA,104
2
+ oqtopus/oqtopus.py,sha256=BF_JSF2oOCzc8Qr7Z0B7FJdYrdAR3FR9L7oXh3QatL4,1860
3
+ oqtopus/oqtopus_plugin.py,sha256=Mpyk6xIgZ1wehBzv70xc6OfddiHQYfXnU6-2E6dDihs,5815
4
+ oqtopus/core/module.py,sha256=47iDvEOXFNWY77cbi7LhQs5qTUwRNuauieqNTPf9UKY,4766
5
+ oqtopus/core/module_asset.py,sha256=qr_wwriJ_rZd86EuBo_Rx-MDCDJNYA6odhk6F-Z6YFA,467
6
+ oqtopus/core/module_package.py,sha256=sYCnKMOMW4R9ULP3oresDNMAaFEb8y_pLa4Lvjdl7RI,3958
7
+ oqtopus/core/modules_config.py,sha256=iEN_JYuFuGpF4dyfnmcJPfp_bIzrn_PNbq9G1DElyCg,186
8
+ oqtopus/core/package_prepare_task.py,sha256=YqIjUbCqDyCd5t0Un71ECgY0LW_uFFxuXyO701nXZ_M,5483
9
+ oqtopus/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ oqtopus/gui/about_dialog.py,sha256=dDNwHxKf_M82Z-TKmXW1fXmnI_WSV_7MShqz05trzRw,2345
11
+ oqtopus/gui/database_connection_widget.py,sha256=7wFO1ysGwoNoXFFakNz6TktwOm28z3dRmbVxavIXX0E,6375
12
+ oqtopus/gui/database_create_dialog.py,sha256=afltzI1s9B0QGnZl6mgsX-0EvwOUArMu1Vxar4RsYvs,9055
13
+ oqtopus/gui/database_duplicate_dialog.py,sha256=Oz8pob6HxZHbV5Thcrhy4dPvGEI4_brSxw9KIcTc2ZE,4017
14
+ oqtopus/gui/logs_widget.py,sha256=lxP0rZYUF4ahR7RtM3SJCbk5nk70SVC9Ien6TvBsflY,6698
15
+ oqtopus/gui/main_dialog.py,sha256=7nxn4vL5fIege0qBPP1mrOp5jP0YWXFJ_k_ywGeKD8M,6362
16
+ oqtopus/gui/module_selection_widget.py,sha256=57M9sM_VhD5lAfxqOxEPWUHiB2Ty6EQQkRnvAZ0VSv8,16116
17
+ oqtopus/gui/module_widget.py,sha256=WEE0paMIbRDfJ2KvIByZtHK4H1TULXLBFb1c4ydQttg,8443
18
+ oqtopus/gui/parameters_groupbox.py,sha256=ZXoIbTDrpoe_SfxyYr7mNbQOi0vHAJSW8cPIXzGKdmE,2938
19
+ oqtopus/gui/plugin_widget.py,sha256=8av8KI3p8gnXOlSssB5-dFVvq4vaLfqGjY9NVSNiBb0,5757
20
+ oqtopus/gui/project_widget.py,sha256=T34MyHzHgKw1Dl6V67MKPneSd9DDgrWhuhj7mrcvjSg,6696
21
+ oqtopus/gui/settings_dialog.py,sha256=wgwVCuAIBh9iLrs9y5HfE99LrTV0rEYbL3frMBlW0cQ,1547
22
+ oqtopus/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ oqtopus/ui/about_dialog.ui,sha256=2oa5u3LIvN3prHyELUG-bwDuEHlBn9-uuA4CwYsEARo,6236
24
+ oqtopus/ui/database_connection_widget.ui,sha256=0hLBaOx0KcLTH6RlkziVj-tsczjHDUGC-3EXQYgcTuE,3729
25
+ oqtopus/ui/database_create_dialog.ui,sha256=4xP4L5wrXAZH7NVdnyiRTgvI-JykLzH5oH-FXHASWQM,8377
26
+ oqtopus/ui/database_duplicate_dialog.ui,sha256=EzMRYhlxsiP_sr9ixBJn4lnefM5R_p1oXx4RCyMAj9U,3826
27
+ oqtopus/ui/logs_widget.ui,sha256=oAgEtRUBXB-DzLC0vmBP-PEA-Uu3d3ppFm0ahs1jHQI,2785
28
+ oqtopus/ui/main_dialog.ui,sha256=mB_VeJ-4wXJm3UTS5leGg_ZgFwgBJaS1QruBqnYMh6U,2650
29
+ oqtopus/ui/module_selection_widget.ui,sha256=IWfoWT5vHoayQPoOPIHOJlg4JdNmVX8DHFQnTIv-Hdk,5646
30
+ oqtopus/ui/module_widget.ui,sha256=2sm0J-qb4CRiKaGk5lyg6AMWlq0d2hE0IW5OSYmJQZo,5662
31
+ oqtopus/ui/plugin_widget.ui,sha256=osJ_QwzmXahV5fEHk4WfUjBBQ7jdsrL4pixiMF2jURA,2570
32
+ oqtopus/ui/project_widget.ui,sha256=5YqSjHR8mQFmHzbSB2M6JnNfrpkqhlRC0N9MSlgcXY8,1600
33
+ oqtopus/ui/settings_dialog.ui,sha256=3PqxTMo22Ola1zl6XkwhXCi6G-uum6g_1-nbjSXWilI,2216
34
+ oqtopus/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
+ oqtopus/utils/plugin_utils.py,sha256=v-Oxu2zs8tQWzEdHnwEl1mseapyvpPS-lHimJNK2zHY,5702
36
+ oqtopus/utils/qt_utils.py,sha256=HPe9tOQQH9R9xZp4rGphVhSJO7220q368xmreDu5-6g,3243
37
+ oqtopus/utils/tmmtlogging.py,sha256=BSAPrhQGCuH2boMG4bP8QFyLfoss1uR4pO_pXjTA1eQ,1733
38
+ oqtopus/utils/translation.py,sha256=p1d5N6CYIf94fGYdPQnJamdum9MVBlPkJ24c557rqdg,2647
39
+ oqtopus-0.1.19.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
40
+ tests/__init__.py,sha256=z5CxS92efenLcDm64Sifx26EjZBCWPO4oVvaEEHJJ6w,444
41
+ tests/test_plugin_load.py,sha256=HuVLdrsn2PSjKIrvcLj0EH7vNE8-0jBMmHZHihsqB3Q,517
42
+ oqtopus-0.1.19.dist-info/METADATA,sha256=Dc2t_sJ8p4179aLZl3aOPterDx9_sB31H9STTDN5LhY,21475
43
+ oqtopus-0.1.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
+ oqtopus-0.1.19.dist-info/top_level.txt,sha256=i4DHi21kcGIzrF8DlgsKj-UCENHg_NebTRac7cwt32A,14
45
+ oqtopus-0.1.19.dist-info/RECORD,,
@@ -1,43 +0,0 @@
1
- oqtopus/__init__.py,sha256=PUl5ObSgoyF6tcNphBip9Rff8lul0t9VobiwsLKwgFA,104
2
- oqtopus/oqtopus.py,sha256=e70YIN0xAB33jHOmfoK8-zP0CeZc6jCV5dAf8rAIbB4,2032
3
- oqtopus/oqtopus_plugin.py,sha256=yzrM_sJyZQ-MVYhvG-bILdPF6jH415z9LK9xKEpT5Sg,5995
4
- oqtopus/core/module.py,sha256=XOGI7R_2LyoscXAA-hCTKu7KjJ6ppAPgVFwrtSBiWTA,4631
5
- oqtopus/core/module_asset.py,sha256=gMHauU5AdAK9gKlsjN1cmbXIca_Xwzb0QcnLBBrJ6f4,403
6
- oqtopus/core/module_package.py,sha256=15kqjw0LOx8Iy9N3zMwKhNee4k5q_2g1atu19dC12wg,3645
7
- oqtopus/core/modules_config.py,sha256=iEN_JYuFuGpF4dyfnmcJPfp_bIzrn_PNbq9G1DElyCg,186
8
- oqtopus/core/package_prepare_task.py,sha256=Eoq9i6tpaik8dpnMef8CKBlmEdXs16krogrQU6vobXI,4839
9
- oqtopus/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- oqtopus/gui/about_dialog.py,sha256=dDNwHxKf_M82Z-TKmXW1fXmnI_WSV_7MShqz05trzRw,2345
11
- oqtopus/gui/database_connection_widget.py,sha256=Uyhwj_jUY5nM5UTv95zkXBoBwbTwX4HsNvVuUzkcY7o,6096
12
- oqtopus/gui/database_create_dialog.py,sha256=afltzI1s9B0QGnZl6mgsX-0EvwOUArMu1Vxar4RsYvs,9055
13
- oqtopus/gui/database_duplicate_dialog.py,sha256=Oz8pob6HxZHbV5Thcrhy4dPvGEI4_brSxw9KIcTc2ZE,4017
14
- oqtopus/gui/logs_widget.py,sha256=B9Kbwt6cD40CV5mfcyaHZ5foJIPvWRednbxIRdeRgpU,6593
15
- oqtopus/gui/main_dialog.py,sha256=6nW76FzOg1w0B4bQl6l21YW03xfEf40fOxYb1Jv5WQI,5886
16
- oqtopus/gui/module_selection_widget.py,sha256=cWQFKDCslXYQL1vbfPOQwFYMkeRxxdThajY-dbpZc-w,15169
17
- oqtopus/gui/module_widget.py,sha256=g86mgctjfgkkGr57ynEb98jWkQRNtbDbDLpXwARSgO8,7591
18
- oqtopus/gui/parameters_groupbox.py,sha256=Lgwv76epIvZOZA0y9sxNcbuZ0Tun-ObUzvOa6eM3EzM,2842
19
- oqtopus/gui/project_widget.py,sha256=qAUF7pJ3B-mBv3AMC9lg3kdQvt6c4Z5xi4zl-cvpx2g,5796
20
- oqtopus/gui/settings_dialog.py,sha256=wgwVCuAIBh9iLrs9y5HfE99LrTV0rEYbL3frMBlW0cQ,1547
21
- oqtopus/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- oqtopus/ui/about_dialog.ui,sha256=2oa5u3LIvN3prHyELUG-bwDuEHlBn9-uuA4CwYsEARo,6236
23
- oqtopus/ui/database_connection_widget.ui,sha256=0hLBaOx0KcLTH6RlkziVj-tsczjHDUGC-3EXQYgcTuE,3729
24
- oqtopus/ui/database_create_dialog.ui,sha256=wM_x54bfgdSaShdx6MwBgDx_R-O_ckeoynEhFjs-Sws,8261
25
- oqtopus/ui/database_duplicate_dialog.ui,sha256=EzMRYhlxsiP_sr9ixBJn4lnefM5R_p1oXx4RCyMAj9U,3826
26
- oqtopus/ui/logs_widget.ui,sha256=oAgEtRUBXB-DzLC0vmBP-PEA-Uu3d3ppFm0ahs1jHQI,2785
27
- oqtopus/ui/main_dialog.ui,sha256=idp-jcLKdxbI22JrmXHsZtgmfT9YvOXkngMKxqqOJF0,4682
28
- oqtopus/ui/module_selection_widget.ui,sha256=AqLPBtX1B8Q03s-JB75lDP__OkhGH04cFVjZnoFwurw,4849
29
- oqtopus/ui/module_widget.ui,sha256=2sm0J-qb4CRiKaGk5lyg6AMWlq0d2hE0IW5OSYmJQZo,5662
30
- oqtopus/ui/project_widget.ui,sha256=flrADzGgDL04l2VdcTltn1IyrmE42tEjYtWXAReKdvc,1596
31
- oqtopus/ui/settings_dialog.ui,sha256=3PqxTMo22Ola1zl6XkwhXCi6G-uum6g_1-nbjSXWilI,2216
32
- oqtopus/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- oqtopus/utils/plugin_utils.py,sha256=v-Oxu2zs8tQWzEdHnwEl1mseapyvpPS-lHimJNK2zHY,5702
34
- oqtopus/utils/qt_utils.py,sha256=HPe9tOQQH9R9xZp4rGphVhSJO7220q368xmreDu5-6g,3243
35
- oqtopus/utils/tmmtlogging.py,sha256=BSAPrhQGCuH2boMG4bP8QFyLfoss1uR4pO_pXjTA1eQ,1733
36
- oqtopus/utils/translation.py,sha256=p1d5N6CYIf94fGYdPQnJamdum9MVBlPkJ24c557rqdg,2647
37
- oqtopus-0.1.17.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
38
- tests/__init__.py,sha256=z5CxS92efenLcDm64Sifx26EjZBCWPO4oVvaEEHJJ6w,444
39
- tests/test_plugin_load.py,sha256=HuVLdrsn2PSjKIrvcLj0EH7vNE8-0jBMmHZHihsqB3Q,517
40
- oqtopus-0.1.17.dist-info/METADATA,sha256=P3y3FtZ88V14L60n7isCWXQ9OlNVnapMyKxWX0uvwnA,21475
41
- oqtopus-0.1.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
42
- oqtopus-0.1.17.dist-info/top_level.txt,sha256=i4DHi21kcGIzrF8DlgsKj-UCENHg_NebTRac7cwt32A,14
43
- oqtopus-0.1.17.dist-info/RECORD,,