Skip to content

Commit

Permalink
Multi parent folders validator (#349)
Browse files Browse the repository at this point in the history
* Show a warning when a plugin has multiple parent folders

* Add a multi parents plugin to testfiles
  • Loading branch information
Xpirix authored Jan 31, 2024
1 parent 5054f5d commit 9a87f0f
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 4 deletions.
48 changes: 47 additions & 1 deletion qgis-app/plugins/tests/test_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,50 @@ def test_plugin_without_license(self):
charset="utf8",
)
)
)
)

class TestMultipleParentFoldersValidator(TestCase):
"""Test if zipfile contains multiple parent folders """

def setUp(self) -> None:
multi_parents_plugin = os.path.join(TESTFILE_DIR, "multi_parents_plugin.zip_")
self.multi_parents_plugin_package = open(multi_parents_plugin, "rb")
valid_plugin = os.path.join(TESTFILE_DIR, "valid_plugin.zip_")
self.single_parent_plugin_package = open(valid_plugin, "rb")

def tearDown(self):
self.multi_parents_plugin_package.close()
self.single_parent_plugin_package.close()

def _get_value_by_attribute(self, attribute, data):
for key, value in data:
if key == attribute:
return value
return None
def test_plugin_with_multiple_parents(self):
result = validator(
InMemoryUploadedFile(
self.multi_parents_plugin_package,
field_name="tempfile",
name="testfile.zip",
content_type="application/zip",
size=39889,
charset="utf8",
)
)
multiple_parent_folders = self._get_value_by_attribute('multiple_parent_folders', result)
self.assertIsNotNone(multiple_parent_folders)

def test_plugin_with_single_parent(self):
result = validator(
InMemoryUploadedFile(
self.single_parent_plugin_package,
field_name="tempfile",
name="testfile.zip",
content_type="application/zip",
size=39889,
charset="utf8",
)
)
multiple_parent_folders = self._get_value_by_attribute('multiple_parent_folders', result)
self.assertIsNone(multiple_parent_folders)
Binary file not shown.
16 changes: 13 additions & 3 deletions qgis-app/plugins/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,20 @@ def validator(package):
errors="replace",
)

# Checks that package_name exists
# Metadata list, also usefull to pass warnings to the main view
metadata = []

namelist = zip.namelist()
# Check if the zip file contains multiple parent folders
# If it is, show a warning for now
try:
parent_folders = list(set([str(name).split('/')[0] for name in namelist]))
if len(parent_folders) > 1:
metadata.append(("multiple_parent_folders", ', '.join(parent_folders)))
except:
pass

# Checks that package_name exists
try:
package_name = namelist[0][: namelist[0].index("/")]
except:
Expand All @@ -238,8 +250,6 @@ def validator(package):
if initname not in namelist:
raise ValidationError(_("Cannot find __init__.py in plugin package."))

# Checks metadata
metadata = []
# First parse metadata.txt
if metadataname in namelist:
try:
Expand Down
33 changes: 33 additions & 0 deletions qgis-app/plugins/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,17 @@ def plugin_upload(request):
)
del form.cleaned_data["license_recommended"]

if form.cleaned_data.get("multiple_parent_folders"):
parent_folders = form.cleaned_data.get("multiple_parent_folders")
messages.warning(
request,
_(
f"Your plugin includes multiple parent folders: {parent_folders}. Please be aware that only the first folder has been recognized. It is strongly advised to have a single parent folder."
),
fail_silently=True,
)
del form.cleaned_data["multiple_parent_folders"]

except (IntegrityError, ValidationError, DjangoUnicodeDecodeError) as e:
connection.close()
messages.error(request, e, fail_silently=True)
Expand Down Expand Up @@ -1202,6 +1213,17 @@ def _version_create(request, plugin, version, is_trusted=False):
)
del form.cleaned_data["license_recommended"]

if form.cleaned_data.get("multiple_parent_folders"):
parent_folders = form.cleaned_data.get("multiple_parent_folders")
messages.warning(
request,
_(
f"Your plugin includes multiple parent folders: {parent_folders}. Please be aware that only the first folder has been recognized. It is strongly advised to have a single parent folder."
),
fail_silently=True,
)
del form.cleaned_data["multiple_parent_folders"]

_main_plugin_update(request, new_object.plugin, form)
_check_optional_metadata(form, request)
return HttpResponseRedirect(new_object.plugin.get_absolute_url())
Expand Down Expand Up @@ -1276,6 +1298,17 @@ def _version_update(request, plugin, version, is_trusted=False):
)
del form.cleaned_data["license_recommended"]

if form.cleaned_data.get("multiple_parent_folders"):
parent_folders = form.cleaned_data.get("multiple_parent_folders")
messages.warning(
request,
_(
f"Your plugin includes multiple parent folders: {parent_folders}. Please be aware that only the first folder has been recognized. It is strongly advised to have a single parent folder."
),
fail_silently=True,
)
del form.cleaned_data["multiple_parent_folders"]

except (IntegrityError, ValidationError, DjangoUnicodeDecodeError) as e:
messages.error(request, e, fail_silently=True)
connection.close()
Expand Down

0 comments on commit 9a87f0f

Please sign in to comment.