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 b192b857..4bf084d9 100644 --- a/qgis-app/plugins/tests/test_validator.py +++ b/qgis-app/plugins/tests/test_validator.py @@ -195,27 +195,41 @@ def test_zipfile_with_gitignore(self, mock_namelist): ) -# This should be just a warning for now according to https://github.com/qgis/QGIS-Django/issues/38#issuecomment-1824010198 -# class TestLicenseValidator(TestCase): -# """Test if zipfile contains LICENSE file """ - -# def setUp(self) -> None: -# plugin_without_license = os.path.join(TESTFILE_DIR, "plugin_without_license.zip_") -# self.invalid_plugin = open(plugin_without_license, "rb") - -# def tearDown(self): -# self.invalid_plugin.close() - -# def test_zipfile_without_license(self): -# self.assertRaises( -# ValidationError, -# 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 +class TestLicenseValidator(TestCase): + """Test if zipfile contains LICENSE file """ + + def setUp(self) -> None: + plugin_without_license = os.path.join(TESTFILE_DIR, "plugin_without_license.zip_") + self.invalid_plugin = open(plugin_without_license, "rb") + + def tearDown(self): + self.invalid_plugin.close() + + def test_new_plugin_without_license(self): + self.assertRaises( + ValidationError, + validator, + InMemoryUploadedFile( + self.invalid_plugin, + field_name="tempfile", + name="testfile.zip", + content_type="application/zip", + 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 069e0c24..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,12 +238,6 @@ def validator(package): if initname not in namelist: raise ValidationError(_("Cannot find __init__.py in plugin package.")) - # Checks for LICENCE file precense - # This should be just a warning for now according to https://github.com/qgis/QGIS-Django/issues/38#issuecomment-1824010198 - # licensename = package_name + "/LICENSE" - # if licensename not in namelist: - # raise ValidationError(_("Cannot find LICENSE in plugin package.")) - # Checks metadata metadata = [] # First parse metadata.txt @@ -330,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()