Skip to content

Commit f58f63a

Browse files
committed
Fix crash due to missing metadata cache
1 parent de0e3f9 commit f58f63a

File tree

3 files changed

+89
-83
lines changed

3 files changed

+89
-83
lines changed

plugin_exporter/metadata.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
name=Plugin Exporter
77
qgisMinimumVersion=3.0
88
description=Exports plugins
9-
version=0.1
9+
version=0.1.0
1010
author=Francis Lapointe
1111
1212

@@ -23,7 +23,7 @@ hasProcessingProvider=no
2323
# changelog=
2424

2525
# Tags are comma separated with spaces allowed
26-
tags=python, qgis, plugin
26+
tags=python, qgis, plugin, importer, exporter
2727

2828
homepage=https://github.com/Scriptbash/PluginExporter
2929
category=Plugins

plugin_exporter/plugin_exporter.py

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,18 @@
2323
"""
2424
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
2525
from qgis.PyQt.QtGui import QIcon
26-
from qgis.PyQt.QtWidgets import QAction, QLabel, QCheckBox, QComboBox
27-
from qgis.gui import QgsPluginManagerInterface
26+
from qgis.PyQt.QtWidgets import QAction, QLabel, QCheckBox
2827
from qgis.core import Qgis
2928
import qgis.utils
30-
31-
# Initialize Qt resources from file resources.py
32-
from .resources import *
33-
# Import the code for the dialog
34-
from .plugin_exporter_dialog import PluginExporterDialog
3529
import pyplugin_installer
3630
import os.path
3731
import csv
3832
import json
3933
import pathlib
34+
# Initialize Qt resources from file resources.py
35+
from .resources import *
36+
# Import the code for the dialog
37+
from .plugin_exporter_dialog import PluginExporterDialog
4038

4139

4240
class PluginExporter:
@@ -92,7 +90,6 @@ def tr(self, message):
9290
# noinspection PyTypeChecker,PyArgumentList,PyCallByClass
9391
return QCoreApplication.translate('PluginExporter', message)
9492

95-
9693
def add_action(
9794
self,
9895
icon_path,
@@ -180,7 +177,6 @@ def initGui(self):
180177
# will be set False in run()
181178
self.first_start = True
182179

183-
184180
def unload(self):
185181
"""Removes the plugin menu item and icon from QGIS GUI."""
186182
for action in self.actions:
@@ -189,15 +185,15 @@ def unload(self):
189185
action)
190186
self.iface.removeToolBarIcon(action)
191187

192-
193188
def run(self):
194189
"""Run method that performs all the real work"""
195190

196191
# Create the dialog with elements (after translation) and keep reference
197192
# Only create GUI ONCE in callback, so that it will only load when the plugin is started
198-
if self.first_start == True:
193+
if self.first_start:
199194
self.first_start = False
200195
self.dlg = PluginExporterDialog()
196+
pyplugin_installer.instance().reloadAndExportData() # Generate metadata cache
201197
self.get_plugins()
202198
self.dlg.btn_select_all.clicked.connect(self.select_all)
203199
self.dlg.btn_deselect_all.clicked.connect(self.deselect_all)
@@ -218,19 +214,24 @@ def run(self):
218214
elif self.dlg.rd_import.isChecked():
219215
self.import_plugins()
220216

217+
# Creates a list of all the plugin IDs
221218
def get_plugins(self):
222-
if self.dlg.chk_active_plugins.isChecked():
219+
if self.dlg.chk_active_plugins.isChecked(): # Only active plugins
223220
plugins = qgis.utils.active_plugins
224221
else:
225-
plugins = qgis.utils.available_plugins
222+
plugins = qgis.utils.available_plugins # All plugins
226223
self.add_plugins_to_table(plugins)
227224

225+
# Adds all the installed plugins into the table
228226
def add_plugins_to_table(self, plugins):
229227
self.plugins_metadata.clear()
230228
self.clear_plugins_table()
231229
table = self.dlg.table_plugins
230+
232231
for plugin in plugins:
233232
metadata = self.iface.pluginManagerInterface().pluginMetadata(plugin)
233+
if metadata is None:
234+
continue # Skip plugins with no metadata
234235
if self.dlg.chk_official_plugins.isChecked():
235236
if metadata['zip_repository'] == 'QGIS Official Plugin Repository':
236237
self.plugins_metadata.append(metadata) # Adds the plugin metadata to the list
@@ -257,25 +258,29 @@ def add_plugins_to_table(self, plugins):
257258

258259
table.resizeColumnsToContents()
259260

261+
# Checks all the plugin checkboxes
260262
def select_all(self):
261263
table = self.dlg.table_plugins
262264
rows = table.rowCount()
263265
for row in range(rows):
264266
checkbox = table.cellWidget(row, 0)
265267
checkbox.setChecked(True)
266268

269+
# Uncheck all the plugin checkboxes
267270
def deselect_all(self):
268271
table = self.dlg.table_plugins
269272
rows = table.rowCount()
270273
for row in range(rows):
271274
checkbox = table.cellWidget(row, 0)
272275
checkbox.setChecked(False)
273276

277+
# Deletes every row of the table
274278
def clear_plugins_table(self):
275279
table = self.dlg.table_plugins
276280
while table.rowCount() > 0:
277281
table.removeRow(0)
278282

283+
#Exports the selected plugin into a .csv or json file
279284
def export_plugins(self):
280285
file_format = self.dlg.combo_file_format.currentText()
281286
output_file = self.dlg.file_output_export.filePath()
@@ -289,10 +294,8 @@ def export_plugins(self):
289294
current_widget = table.cellWidget(row, col)
290295
if isinstance(current_widget, QCheckBox):
291296
if not current_widget.isChecked():
292-
break
297+
break # Don't add plugins that are not checked
293298
elif isinstance(current_widget, QLabel):
294-
# plugin_list.append(current_widget.text())
295-
# next((item for item in dicts if item["name"] == "Pam"), None)
296299
current_plugin = next(
297300
(item for item in self.plugins_metadata if item["name"] == current_widget.text()), None)
298301
if current_plugin:
@@ -301,10 +304,10 @@ def export_plugins(self):
301304
if output_file:
302305
if file_format == '.csv':
303306
with open(output_file, 'w', encoding='utf8', newline='') as f:
304-
keys = plugin_list[0].keys()
305-
dict_writer = csv.DictWriter(f, keys)
306-
dict_writer.writeheader()
307-
dict_writer.writerows(plugin_list)
307+
keys = plugin_list[0].keys()
308+
dict_writer = csv.DictWriter(f, keys)
309+
dict_writer.writeheader()
310+
dict_writer.writerows(plugin_list)
308311
self.iface.messageBar().pushSuccess("Success", "Selected plugins were exported successfully.")
309312
elif file_format == '.json':
310313
with open(output_file, 'w') as file:
@@ -319,11 +322,12 @@ def export_plugins(self):
319322
"At least one plugin must be selected.",
320323
level=Qgis.Critical)
321324

325+
# Installs the plugins read from a .csv or .json file
322326
def import_plugins(self):
323327
input_file = self.dlg.file_input_import.filePath()
324328
file_extension = pathlib.Path(input_file).suffix
325329
installed_plugins = qgis.utils.available_plugins
326-
pyplugin_installer.instance().fetchAvailablePlugins()
330+
pyplugin_installer.instance().fetchAvailablePlugins(True)
327331

328332
if file_extension == '.csv':
329333
try:
@@ -361,6 +365,7 @@ def import_plugins(self):
361365
"Could not install " + plugin['name'] + ".",
362366
level=Qgis.Critical)
363367

368+
# Disables and enables widgets
364369
def toggle_widget(self):
365370
if self.dlg.rd_import.isChecked():
366371
self.dlg.file_output_export.setEnabled(False)
@@ -373,6 +378,7 @@ def toggle_widget(self):
373378
self.dlg.file_output_export.setEnabled(True)
374379
self.dlg.combo_file_format.setEnabled(True)
375380

381+
# Sets the file extension filter for the QgsFileWidget
376382
def set_filter(self):
377383
if self.dlg.combo_file_format.currentText() == '.json':
378384
self.dlg.file_output_export.setFilter('*.json')

0 commit comments

Comments
 (0)