From 08f01b4f62a2a75f05947ebf7f39d46c60ff249b Mon Sep 17 00:00:00 2001 From: Lova ANDRIARIMALALA <43842786+Xpirix@users.noreply.github.com> Date: Fri, 24 Nov 2023 07:07:31 +0300 Subject: [PATCH] Fix license requirement (#311) * Fix license file requirement * Show warning text for missing license when updating plugins --- qgis-app/plugins/forms.py | 2 +- qgis-app/plugins/tests/test_validator.py | 17 ++++++++++++++++- qgis-app/plugins/validator.py | 19 +++++++++++++------ qgis-app/plugins/views.py | 22 ++++++++++++++++++++++ 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/qgis-app/plugins/forms.py b/qgis-app/plugins/forms.py index 600986de..8dabcf5f 100644 --- a/qgis-app/plugins/forms.py +++ b/qgis-app/plugins/forms.py @@ -180,7 +180,7 @@ def clean_package(self): """ package = self.cleaned_data.get("package") try: - self.cleaned_data.update(validator(package)) + self.cleaned_data.update(validator(package, plugin_is_new=True)) except ValidationError as e: msg = _( "There were errors reading plugin package (please check also your plugin's metadata)." diff --git a/qgis-app/plugins/tests/test_validator.py b/qgis-app/plugins/tests/test_validator.py index 13d5af3a..4bf084d9 100644 --- a/qgis-app/plugins/tests/test_validator.py +++ b/qgis-app/plugins/tests/test_validator.py @@ -205,7 +205,7 @@ def setUp(self) -> None: def tearDown(self): self.invalid_plugin.close() - def test_zipfile_without_license(self): + def test_new_plugin_without_license(self): self.assertRaises( ValidationError, validator, @@ -217,4 +217,19 @@ def test_zipfile_without_license(self): size=39889, charset="utf8", ), + plugin_is_new=True + ) + + def test_update_plugin_without_license(self): + self.assertTrue( + validator( + InMemoryUploadedFile( + self.invalid_plugin, + field_name="tempfile", + name="testfile.zip", + content_type="application/zip", + size=39889, + charset="utf8", + ) + ) ) \ No newline at end of file diff --git a/qgis-app/plugins/validator.py b/qgis-app/plugins/validator.py index 930eeb77..98f5ca54 100644 --- a/qgis-app/plugins/validator.py +++ b/qgis-app/plugins/validator.py @@ -146,7 +146,7 @@ def _check_url_link(url: str, forbidden_url: str, metadata_attr: str) -> None: raise error_check_if_exist -def validator(package): +def validator(package, plugin_is_new=False): """ Analyzes a zipped file, returns metadata if success, False otherwise. If the new icon metadata is found, an inmemory file object is also returned @@ -155,6 +155,7 @@ def validator(package): * size <= PLUGIN_MAX_UPLOAD_SIZE * zip contains __init__.py in first level dir + * Check for LICENCE file * mandatory metadata: ('name', 'description', 'version', 'qgisMinimumVersion', 'author', 'email') * package_name regexp: [A-Za-z][A-Za-z0-9-_]+ * author regexp: [^/]+ @@ -237,11 +238,6 @@ def validator(package): if initname not in namelist: raise ValidationError(_("Cannot find __init__.py in plugin package.")) - # Checks for LICENCE file precense - licensename = package_name + "/LICENSE" - if licensename not in namelist: - raise ValidationError(_("Cannot find LICENSE in plugin package.")) - # Checks metadata metadata = [] # First parse metadata.txt @@ -329,6 +325,17 @@ def validator(package): _check_url_link(dict(metadata).get("repository"), "http://repo", "Repository") _check_url_link(dict(metadata).get("homepage"), "http://homepage", "Home page") + + # Checks for LICENCE file presence + # This should be just a warning for now (for new version upload) + # according to https://github.com/qgis/QGIS-Django/issues/38#issuecomment-1824010198 + licensename = package_name + "/LICENSE" + if licensename not in namelist: + if plugin_is_new: + raise ValidationError(_("Cannot find LICENSE in the plugin package. This file is required for a new plugin, please consider adding it to the plugin package.")) + else: + metadata.append(("license_recommended", "Yes")) + zip.close() del zip diff --git a/qgis-app/plugins/views.py b/qgis-app/plugins/views.py index 487d22ad..bcf8085a 100644 --- a/qgis-app/plugins/views.py +++ b/qgis-app/plugins/views.py @@ -956,6 +956,17 @@ def version_create(request, package_name): version_notify(new_object) if form.cleaned_data.get("icon_file"): form.cleaned_data["icon"] = form.cleaned_data.get("icon_file") + + if form.cleaned_data.get("license_recommended"): + messages.warning( + request, + _( + "Cannot find LICENSE in the plugin package. This file is not required for updating the plugin but is recommended, please consider adding it to the plugin package." + ), + fail_silently=True, + ) + del form.cleaned_data["license_recommended"] + _main_plugin_update(request, new_object.plugin, form) _check_optional_metadata(form, request) return HttpResponseRedirect(new_object.plugin.get_absolute_url()) @@ -1001,6 +1012,17 @@ def version_update(request, package_name, version): _main_plugin_update(request, new_object.plugin, form) msg = _("The Plugin Version has been successfully updated.") messages.success(request, msg, fail_silently=True) + + if form.cleaned_data.get("license_recommended"): + messages.warning( + request, + _( + "Cannot find LICENSE in the plugin package. This file is not required for updating the plugin but is recommended, please consider adding it to the plugin package." + ), + fail_silently=True, + ) + del form.cleaned_data["license_recommended"] + except (IntegrityError, ValidationError, DjangoUnicodeDecodeError) as e: messages.error(request, e, fail_silently=True) connection.close()