scrutiny/scrutiny/projects/management/commands/scrutinise.py

72 lines
2.9 KiB
Python

import multiprocessing
import multiprocessing.pool
import requests
from django.core.management.base import BaseCommand
import django.utils.timezone
from scrutiny.projects.models import InstalledService, Module, Version, InstalledVersion
class Command(BaseCommand):
help = 'Scrutiny services for changes'
def handle(self, verbosity, *args, **options):
self.verbose = int(verbosity) > 1
def scrutinise(service):
if not service.url.endswith('/'):
service.url = '%s/' % service.url
if self.verbose:
print('Checking %s' % service.url)
try:
response = requests.get('%s__version__' % service.url, timeout=5, verify=True)
response.raise_for_status()
except requests.RequestException as e:
print('Error with %s (%r)' % (service.url, e))
return
versions = response.json()
current_modules = set([x for x in service.service.get_modules(platforms=[service.platform])])
seen_modules = set()
for module_name, version_string in versions.items():
try:
module = Module.objects.get(name=module_name)
except Module.DoesNotExist:
module = Module()
module.name = module_name
module.save()
seen_modules.add(module)
try:
version, created = Version.objects.get_or_create(module=module, version=version_string)
except Version.MultipleObjectsReturned:
# a race condition occured earlier, gently ignore
version = Version.objects.filter(module=module, version=version_string).first()
try:
installed_version = InstalledVersion.objects.get(service=service, version=version)
except InstalledVersion.DoesNotExist:
installed_version = InstalledVersion()
installed_version.service = service
installed_version.version = version
installed_version.timestamp = django.utils.timezone.now()
installed_version.save()
uninstalled_modules = current_modules - seen_modules
for module in uninstalled_modules:
try:
version = Version.objects.get(module=module, version='')
except Version.DoesNotExist:
version = module.version_set.create(version='')
installed_version = InstalledVersion()
installed_version.service = service
installed_version.version = version
installed_version.timestamp = django.utils.timezone.now()
installed_version.save()
with multiprocessing.pool.ThreadPool() as pool:
list(pool.imap_unordered(scrutinise, InstalledService.objects.all()))