-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added custom command to validate existing plugins on server
- Loading branch information
suman
committed
Apr 26, 2021
1 parent
ae9478f
commit 743c6e2
Showing
2 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
108
qgis-app/plugins/management/commands/validate_existing_plugins.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
"""A command to validate the existing zipfile Plugin Packages""" | ||
|
||
import os | ||
from django.conf import settings | ||
from django.core.files.uploadedfile import InMemoryUploadedFile | ||
from django.core.mail import send_mail | ||
from django.core.management.base import BaseCommand | ||
from django.contrib.sites.models import Site | ||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
from plugins.models import PluginVersion | ||
from plugins.validator import validator | ||
|
||
|
||
DOMAIN = Site.objects.get_current().domain | ||
|
||
|
||
def send_email_notification(plugin, version, message, url_version, recipients): | ||
|
||
message = ('\r\nPlease update ' | ||
'Plugin: %s ' | ||
'- Version: %s\r\n' | ||
'\r\nIt failed to pass validation with message:' | ||
'\r\n%s\r\n' | ||
'\r\nLink: %s') % (plugin, version, message, url_version) | ||
send_mail( | ||
subject='Invalid Plugin Metadata Notification', | ||
message=_(message), | ||
from_email=settings.DEFAULT_FROM_EMAIL, | ||
recipient_list=recipients, | ||
fail_silently=True | ||
) | ||
|
||
|
||
def get_recipients_email(plugin): | ||
receipt_email = [] | ||
if plugin.created_by.email: | ||
receipt_email.append(plugin.created_by.email) | ||
if plugin.email: | ||
receipt_email.append(plugin.email) | ||
return receipt_email | ||
|
||
|
||
def validate_zipfile_version(version): | ||
|
||
if not os.path.exists(version.package.url): | ||
return { | ||
'plugin': f'{version.plugin.name}', | ||
'created_by': f'{version.plugin.created_by}', | ||
'version': f'{version.version}', | ||
'msg': [f'File does not exist. Please re-upload.'], | ||
'url': f'http://{DOMAIN}{version.get_absolute_url()}', | ||
'recipients_email': get_recipients_email(version.plugin) | ||
} | ||
|
||
with open(version.package.url, 'rb') as buf: | ||
package = InMemoryUploadedFile( | ||
buf, | ||
'tempfile', | ||
'filename.zip', | ||
'application/zip', | ||
1000000, # ignore the filesize and assume it's 1MB | ||
'utf8') | ||
try: | ||
validator(package) | ||
except Exception as e: | ||
return { | ||
'plugin': f'{version.plugin.name}', | ||
'created_by': f'{version.plugin.created_by}', | ||
'version': f'{version.version}', | ||
'msg': e.messages, | ||
'url': f'http://{DOMAIN}{version.get_absolute_url()}', | ||
'recipients_email': get_recipients_email(version.plugin) | ||
} | ||
return None | ||
|
||
|
||
class Command(BaseCommand): | ||
|
||
help = ('Validate existing Plugins zipfile and send a notification email ' | ||
'for invalid Plugin') | ||
|
||
def handle(self, *args, **options): | ||
self.stdout.write('Validating existing plugins...') | ||
versions = PluginVersion.objects.all() | ||
num_count = 0 | ||
for version in versions: | ||
error_msg = validate_zipfile_version(version) | ||
if error_msg: | ||
send_email_notification( | ||
plugin=error_msg['plugin'], | ||
version=error_msg['version'], | ||
message='\r\n'.join(error_msg['msg']), | ||
url_version=error_msg['url'], | ||
recipients=error_msg['recipients_email'] | ||
) | ||
self.stdout.write( | ||
_('Sent email to %s for Plugin %s - Version %s.') % ( | ||
error_msg['recipients_email'], | ||
error_msg['plugin'], | ||
error_msg['version'] | ||
) | ||
) | ||
num_count += 1 | ||
self.stdout.write( | ||
_('Successfully sent email notification for %s invalid plugins') | ||
% (num_count) | ||
) |
116 changes: 116 additions & 0 deletions
116
qgis-app/plugins/tests/test_validate_existing_plugins.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import os | ||
|
||
from django.contrib.auth.models import User | ||
from django.core import mail | ||
from django.core.files.uploadedfile import InMemoryUploadedFile | ||
from django.test import TestCase, override_settings | ||
|
||
from plugins.models import PluginVersion, Plugin | ||
from plugins.management.commands.validate_existing_plugins import ( | ||
validate_zipfile_version, send_email_notification) | ||
|
||
TESTFILE_DIR = os.path.abspath( | ||
os.path.join(os.path.dirname(__file__), 'testfiles')) | ||
|
||
|
||
@override_settings(MEDIA_ROOT='plugins/tests/testfiles/') | ||
@override_settings(MEDIA_URL='plugins/tests/testfiles/') | ||
class TestValidateExistingPlugin(TestCase): | ||
def setUp(self) -> None: | ||
self.creator = User.objects.create( | ||
username='usertest_creator', | ||
first_name="first_name", | ||
last_name="last_name", | ||
email="[email protected]", | ||
password="passwordtest", | ||
is_active=True) | ||
self.author = User.objects.create( | ||
username='usertest_author', | ||
first_name="author", | ||
last_name="last_name", | ||
email="[email protected]", | ||
password="passwordtest", | ||
is_active=True) | ||
|
||
invalid_plugin = os.path.join( | ||
TESTFILE_DIR, "web_not_exist.zip") | ||
self.invalid_plugin = open(invalid_plugin, 'rb') | ||
|
||
uploaded_zipfile = InMemoryUploadedFile( | ||
self.invalid_plugin, | ||
field_name='tempfile', | ||
name='testfile.zip', | ||
content_type='application/zip', | ||
size=39889, | ||
charset='utf8') | ||
|
||
self.plugin = Plugin.objects.create( | ||
created_by=self.creator, | ||
name='test_plugin', | ||
package_name='test_plugin' | ||
) | ||
|
||
self.version = PluginVersion.objects.create( | ||
plugin=self.plugin, | ||
created_by=self.creator, | ||
version='0.1', | ||
package=uploaded_zipfile, | ||
min_qg_version='3.10', | ||
max_qg_version='3.18' | ||
) | ||
|
||
def tearDown(self) -> None: | ||
self.invalid_plugin.close() | ||
os.remove(self.version.package.url) | ||
|
||
def test_plugin_exist(self): | ||
self.assertEqual(PluginVersion.objects.count(), 1) | ||
self.assertTrue(os.path.exists(self.version.package.url)) | ||
|
||
def test_validate_zipfile_version(self): | ||
expected_value = { | ||
'plugin': 'test_plugin', | ||
'created_by': 'usertest_creator', | ||
'version': '0.1', | ||
'msg': ['Please provide valid url link for Repository in metadata. ' | ||
'This website cannot be reached.'], | ||
'url': 'http://plugins.qgis.org/plugins/test_plugin/version/0.1/', | ||
'recipients_email': ['[email protected]']} | ||
self.assertEqual( | ||
validate_zipfile_version(self.version), | ||
expected_value, | ||
msg=validate_zipfile_version(self.version) | ||
) | ||
|
||
@override_settings( | ||
EMAIL_BACKEND='django.core.mail.backends.console.EmailBackend') | ||
def test_send_email(self): | ||
error_msg = validate_zipfile_version(self.version) | ||
send_email_notification( | ||
plugin=error_msg['plugin'], | ||
version=error_msg['version'], | ||
message='\r\n'.join(error_msg['msg']), | ||
url_version=error_msg['url'], | ||
recipients=error_msg['recipients_email'] | ||
) | ||
|
||
def test_send_email_must_contains(self): | ||
error_msg = validate_zipfile_version(self.version) | ||
send_email_notification( | ||
plugin=error_msg['plugin'], | ||
version=error_msg['version'], | ||
message='\r\n'.join(error_msg['msg']), | ||
url_version=error_msg['url'], | ||
recipients=error_msg['recipients_email'] | ||
) | ||
self.assertEqual(len(mail.outbox), 1) | ||
self.assertEqual( | ||
mail.outbox[0].subject, | ||
'Invalid Plugin Metadata Notification') | ||
self.assertIn( | ||
'Please update Plugin: test_plugin - Version: 0.1', | ||
mail.outbox[0].body) | ||
self.assertIn( | ||
'Please provide valid url link for Repository in metadata. ' | ||
'This website cannot be reached.', | ||
mail.outbox[0].body) |