Skip to content

Commit

Permalink
added custom command to validate existing plugins on server
Browse files Browse the repository at this point in the history
  • Loading branch information
suman committed Apr 26, 2021
1 parent ae9478f commit 743c6e2
Show file tree
Hide file tree
Showing 2 changed files with 224 additions and 0 deletions.
108 changes: 108 additions & 0 deletions qgis-app/plugins/management/commands/validate_existing_plugins.py
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 qgis-app/plugins/tests/test_validate_existing_plugins.py
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)

0 comments on commit 743c6e2

Please sign in to comment.