euscanwww: euscan -> djeuscan
Signed-off-by: Corentin Chary <corentincj@iksaif.net>
This commit is contained in:
		
							
								
								
									
										0
									
								
								euscanwww/djeuscan/management/commands/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								euscanwww/djeuscan/management/commands/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										55
									
								
								euscanwww/djeuscan/management/commands/list-packages.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								euscanwww/djeuscan/management/commands/list-packages.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
from optparse import make_option
 | 
			
		||||
 | 
			
		||||
from django.core.management.base import BaseCommand, CommandError
 | 
			
		||||
from djeuscan.models import Package
 | 
			
		||||
 | 
			
		||||
class Command(BaseCommand):
 | 
			
		||||
    _overlays = {}
 | 
			
		||||
    help = 'List packages'
 | 
			
		||||
 | 
			
		||||
    option_list = BaseCommand.option_list + (
 | 
			
		||||
        make_option('--after',
 | 
			
		||||
            action='store',
 | 
			
		||||
            dest='after',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='After package'),
 | 
			
		||||
        make_option('--before',
 | 
			
		||||
            action='store',
 | 
			
		||||
            dest='before',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Before package'),
 | 
			
		||||
        make_option('--limit',
 | 
			
		||||
            action='store',
 | 
			
		||||
            dest='limit',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='limit'),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def handle(self, *args, **options):
 | 
			
		||||
        after = None
 | 
			
		||||
        before = None
 | 
			
		||||
 | 
			
		||||
        if options['after']:
 | 
			
		||||
            category, name = options['after'].split('/')
 | 
			
		||||
            after = Package.objects.get(category=category, name=name)
 | 
			
		||||
 | 
			
		||||
        if options['before']:
 | 
			
		||||
            category, name = options['before'].split('/')
 | 
			
		||||
            before = Package.objects.get(category=category, name=name)
 | 
			
		||||
 | 
			
		||||
        packages = Package.objects
 | 
			
		||||
 | 
			
		||||
        if after or before:
 | 
			
		||||
            if after:
 | 
			
		||||
                packages = packages.filter(id__gte=after.id)
 | 
			
		||||
            if before:
 | 
			
		||||
                packages = packages.filter(id__lte=before.id)
 | 
			
		||||
        else:
 | 
			
		||||
            packages = packages.all()
 | 
			
		||||
 | 
			
		||||
        if options['limit']:
 | 
			
		||||
            packages = packages[:int(options['limit'])]
 | 
			
		||||
 | 
			
		||||
        for pkg in packages:
 | 
			
		||||
            self.stdout.write('%s/%s\n' % (pkg.category, pkg.name))
 | 
			
		||||
        self.stdout.close()
 | 
			
		||||
							
								
								
									
										24
									
								
								euscanwww/djeuscan/management/commands/regen-rrds.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								euscanwww/djeuscan/management/commands/regen-rrds.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
import datetime
 | 
			
		||||
 | 
			
		||||
from optparse import make_option
 | 
			
		||||
 | 
			
		||||
from django.core.management.base import BaseCommand, CommandError
 | 
			
		||||
from djeuscan.models import HerdLog, MaintainerLog, CategoryLog, WorldLog
 | 
			
		||||
from djeuscan import charts
 | 
			
		||||
 | 
			
		||||
class Command(BaseCommand):
 | 
			
		||||
    _overlays = {}
 | 
			
		||||
    help = 'Regenerate rrd database'
 | 
			
		||||
 | 
			
		||||
    def handle(self, *args, **options):
 | 
			
		||||
        for wlog in WorldLog.objects.all():
 | 
			
		||||
            charts.rrd_update('world', wlog.datetime, wlog)
 | 
			
		||||
 | 
			
		||||
        for clog in CategoryLog.objects.all():
 | 
			
		||||
            charts.rrd_update('category-%s' % clog.category, clog.datetime, clog)
 | 
			
		||||
 | 
			
		||||
        for hlog in HerdLog.objects.all():
 | 
			
		||||
            charts.rrd_update('herd-%d' % hlog.herd.id, hlog.datetime, hlog)
 | 
			
		||||
 | 
			
		||||
        for mlog in MaintainerLog.objects.all():
 | 
			
		||||
            charts.rrd_update('maintainer-%d' % mlog.maintainer.id, mlog.datetime, mlog)
 | 
			
		||||
							
								
								
									
										140
									
								
								euscanwww/djeuscan/management/commands/scan-metadata.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								euscanwww/djeuscan/management/commands/scan-metadata.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
			
		||||
import subprocess
 | 
			
		||||
import portage
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
from portage import versions
 | 
			
		||||
from optparse import make_option
 | 
			
		||||
 | 
			
		||||
from django.db.transaction import commit_on_success
 | 
			
		||||
from django.core.management.base import BaseCommand, CommandError
 | 
			
		||||
from djeuscan.models import Package, Herd, Maintainer
 | 
			
		||||
 | 
			
		||||
from gentoolkit.query import Query
 | 
			
		||||
from gentoolkit.errors import GentoolkitFatalError
 | 
			
		||||
 | 
			
		||||
class Command(BaseCommand):
 | 
			
		||||
    _overlays = {}
 | 
			
		||||
 | 
			
		||||
    option_list = BaseCommand.option_list + (
 | 
			
		||||
        make_option('--all',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='all',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Scan all packages'),
 | 
			
		||||
        make_option('--quiet',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='quiet',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Be quiet'),
 | 
			
		||||
        )
 | 
			
		||||
    args = '<package package ...>'
 | 
			
		||||
    help = 'Scans metadata and fills database'
 | 
			
		||||
 | 
			
		||||
    @commit_on_success
 | 
			
		||||
    def handle(self, *args, **options):
 | 
			
		||||
        self.options = options
 | 
			
		||||
 | 
			
		||||
        if options['all']:
 | 
			
		||||
            for pkg in Package.objects.all():
 | 
			
		||||
                self.scan('%s/%s' % (pkg.category, pkg.name), pkg)
 | 
			
		||||
        elif len(args):
 | 
			
		||||
            for package in args:
 | 
			
		||||
                self.scan(package)
 | 
			
		||||
        else:
 | 
			
		||||
            for package in sys.stdin.readlines():
 | 
			
		||||
                self.scan(package[:-1])
 | 
			
		||||
 | 
			
		||||
    def scan(self, query=None, obj=None):
 | 
			
		||||
        matches = Query(query).find(
 | 
			
		||||
            include_masked=True,
 | 
			
		||||
            in_installed=False,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if not matches:
 | 
			
		||||
            sys.stderr.write(self.style.ERROR("Unknown package '%s'\n" % query))
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
	matches = sorted(matches)
 | 
			
		||||
        pkg = matches.pop()
 | 
			
		||||
	if '9999' in pkg.version and len(matches):
 | 
			
		||||
            pkg = matches.pop()
 | 
			
		||||
 | 
			
		||||
        if not obj:
 | 
			
		||||
            obj, created = Package.objects.get_or_create(category=pkg.category, name=pkg.name)
 | 
			
		||||
        else:
 | 
			
		||||
            created = False
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            obj.homepage = pkg.environment("HOMEPAGE")
 | 
			
		||||
            obj.description = pkg.environment("DESCRIPTION")
 | 
			
		||||
        except GentoolkitFatalError, err:
 | 
			
		||||
            sys.stderr.write(self.style.ERROR("Gentoolkit fatal error: '%s'\n" % str(err)))
 | 
			
		||||
 | 
			
		||||
        if created and not self.options['quiet']:
 | 
			
		||||
            sys.stdout.write('+ [p] %s/%s\n' % (pkg.category, pkg.name))
 | 
			
		||||
 | 
			
		||||
        if pkg.metadata:
 | 
			
		||||
            herds = dict([(herd[0], herd) for herd in pkg.metadata.herds(True)])
 | 
			
		||||
            maintainers = dict([(m.email, m) for m in pkg.metadata.maintainers()])
 | 
			
		||||
 | 
			
		||||
            existing_herds = [h.herd for h in obj.herds.all()]
 | 
			
		||||
            new_herds = set(herds.keys()).difference(existing_herds)
 | 
			
		||||
            old_herds = set(existing_herds).difference(herds.keys())
 | 
			
		||||
 | 
			
		||||
            existing_maintainers = [m.email for m in obj.maintainers.all()]
 | 
			
		||||
            new_maintainers = set(maintainers.keys()).difference(existing_maintainers)
 | 
			
		||||
            old_maintainers = set(existing_maintainers).difference(maintainers.keys())
 | 
			
		||||
 | 
			
		||||
            for herd in obj.herds.all():
 | 
			
		||||
                if herd.email in old_herds:
 | 
			
		||||
                    obj.herds.remove(herd)
 | 
			
		||||
 | 
			
		||||
            for herd in new_herds:
 | 
			
		||||
                herd = self.store_herd(*herds[herd])
 | 
			
		||||
                obj.herds.add(herd)
 | 
			
		||||
 | 
			
		||||
            for maintainer in obj.maintainers.all():
 | 
			
		||||
                if maintainer.email in old_maintainers:
 | 
			
		||||
                    obj.maintainers.remove(maintainer)
 | 
			
		||||
 | 
			
		||||
            for maintainer in new_maintainers:
 | 
			
		||||
                maintainer = maintainers[maintainer]
 | 
			
		||||
                maintainer = self.store_maintainer(maintainer.name, maintainer.email)
 | 
			
		||||
                obj.maintainers.add(maintainer)
 | 
			
		||||
 | 
			
		||||
        obj.save()
 | 
			
		||||
 | 
			
		||||
    def store_herd(self, name, email):
 | 
			
		||||
        if not name:
 | 
			
		||||
            name = '{nil}'
 | 
			
		||||
        name = name.strip("\r").strip("\n").strip("\t").strip()
 | 
			
		||||
 | 
			
		||||
        herd, created = Herd.objects.get_or_create(herd=name)
 | 
			
		||||
 | 
			
		||||
        if created and not self.options['quiet']:
 | 
			
		||||
            sys.stdout.write('+ [h] %s <%s>\n' % (name, email))
 | 
			
		||||
 | 
			
		||||
        herd.email = email
 | 
			
		||||
        herd.save()
 | 
			
		||||
 | 
			
		||||
        return herd
 | 
			
		||||
 | 
			
		||||
    def store_maintainer(self, name, email):
 | 
			
		||||
        if not name:
 | 
			
		||||
            name = email
 | 
			
		||||
        if not name:
 | 
			
		||||
            name = '{nil}'
 | 
			
		||||
 | 
			
		||||
        maintainer, created = Maintainer.objects.get_or_create(email=email)
 | 
			
		||||
 | 
			
		||||
        if created:
 | 
			
		||||
            if not self.options['quiet']:
 | 
			
		||||
                sys.stdout.write('+ [m] %s <%s>\n' % (name.encode('utf-8'), email))
 | 
			
		||||
 | 
			
		||||
            if not maintainer.name or name not in [maintainer.name, email, '{nil}']:
 | 
			
		||||
                maintainer.name = name
 | 
			
		||||
            maintainer.save()
 | 
			
		||||
 | 
			
		||||
        return maintainer
 | 
			
		||||
							
								
								
									
										299
									
								
								euscanwww/djeuscan/management/commands/scan-portage.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								euscanwww/djeuscan/management/commands/scan-portage.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,299 @@
 | 
			
		||||
import subprocess
 | 
			
		||||
import portage
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
from portage import versions
 | 
			
		||||
from optparse import make_option
 | 
			
		||||
 | 
			
		||||
from django.db.transaction import commit_on_success
 | 
			
		||||
from django.core.management.base import BaseCommand, CommandError
 | 
			
		||||
from djeuscan.models import Package, Version, VersionLog
 | 
			
		||||
 | 
			
		||||
class Command(BaseCommand):
 | 
			
		||||
    _overlays = {}
 | 
			
		||||
 | 
			
		||||
    option_list = BaseCommand.option_list + (
 | 
			
		||||
        make_option('--all',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='all',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Scan all packages'),
 | 
			
		||||
        make_option('--purge-packages',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='purge-packages',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Purge old packages'),
 | 
			
		||||
        make_option('--purge-versions',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='purge-versions',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Purge old versions'),
 | 
			
		||||
        make_option('--no-log',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='no-log',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Don\'t store logs'),
 | 
			
		||||
        make_option('--prefetch',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='prefetch',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Prefetch all versions and packages from DB to speedup full scan process.'),
 | 
			
		||||
        make_option('--quiet',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='quiet',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Be quiet'),
 | 
			
		||||
        )
 | 
			
		||||
    args = '[package package ...]'
 | 
			
		||||
    help = 'Scans portage tree and fills database'
 | 
			
		||||
 | 
			
		||||
    _cache = {'packages' : {}, 'versions' : {}}
 | 
			
		||||
 | 
			
		||||
    def cache_hash_package(self, category, name):
 | 
			
		||||
        return '%s/%s' % (category, name)
 | 
			
		||||
 | 
			
		||||
    def cache_store_package(self, package):
 | 
			
		||||
        key = self.cache_hash_package(package.category, package.name)
 | 
			
		||||
        self._cache['packages'][key] = package
 | 
			
		||||
 | 
			
		||||
    def cache_get_package(self, category, name):
 | 
			
		||||
        return self._cache['packages'].get(self.cache_hash_package(category, name))
 | 
			
		||||
 | 
			
		||||
    def cache_hash_version(self, category, name, version, revision, slot, overlay):
 | 
			
		||||
        key = '%s/%s-%s-r%s %s %s' % (category, name,
 | 
			
		||||
                                      version, revision,
 | 
			
		||||
                                      slot, overlay)
 | 
			
		||||
        return key
 | 
			
		||||
 | 
			
		||||
    def cache_get_version(self, category, name, version, revision, slot, overlay):
 | 
			
		||||
        key = self.cache_hash_version(category, name, version, revision, slot, overlay)
 | 
			
		||||
        return self._cache['versions'].get(key)
 | 
			
		||||
 | 
			
		||||
    def cache_store_version(self, version):
 | 
			
		||||
        key = self.cache_hash_version(version.package.category, version.package.name,
 | 
			
		||||
                                      version.version, version.revision, version.slot,
 | 
			
		||||
                                      version.overlay)
 | 
			
		||||
        self._cache['versions'][key] = version
 | 
			
		||||
 | 
			
		||||
    def handle(self, *args, **options):
 | 
			
		||||
        self.options = options
 | 
			
		||||
 | 
			
		||||
        if not options['quiet']:
 | 
			
		||||
            self.stdout.write('Scanning portage tree...\n')
 | 
			
		||||
 | 
			
		||||
        if options['prefetch']:
 | 
			
		||||
            if not options['quiet']:
 | 
			
		||||
                self.stdout.write('Prefetching objects...')
 | 
			
		||||
                self.stdout.flush()
 | 
			
		||||
            for package in Package.objects.all():
 | 
			
		||||
                self.cache_store_package(package)
 | 
			
		||||
            for version in Version.objects.select_related('package').all():
 | 
			
		||||
                self.cache_store_version(version)
 | 
			
		||||
            if not options['quiet']:
 | 
			
		||||
                self.stdout.write('done\n')
 | 
			
		||||
 | 
			
		||||
        if options['all']:
 | 
			
		||||
            self.scan()
 | 
			
		||||
        elif len(args):
 | 
			
		||||
            for package in args:
 | 
			
		||||
                self.scan(package)
 | 
			
		||||
        else:
 | 
			
		||||
            for package in sys.stdin.readlines():
 | 
			
		||||
                self.scan(package[:-1])
 | 
			
		||||
 | 
			
		||||
        if options['purge-versions']:
 | 
			
		||||
            self.purge_versions(options)
 | 
			
		||||
 | 
			
		||||
        if not options['quiet']:
 | 
			
		||||
            self.stdout.write('Done.\n')
 | 
			
		||||
 | 
			
		||||
    def overlays(self):
 | 
			
		||||
        if self._overlays:
 | 
			
		||||
            return self._overlays
 | 
			
		||||
 | 
			
		||||
        env = os.environ
 | 
			
		||||
        env['OVERLAYS_LIST'] = 'all'
 | 
			
		||||
        env['PRINT_COUNT_ALWAYS'] = 'never'
 | 
			
		||||
 | 
			
		||||
        cmd = ['eix', '-!']
 | 
			
		||||
 | 
			
		||||
        output = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env).communicate()[0]
 | 
			
		||||
        output = output.strip().strip('\n').split('\n')
 | 
			
		||||
 | 
			
		||||
        overlay_re = re.compile(r'^\[(?P<key>\d+)] "(?P<name>.*?)"')
 | 
			
		||||
 | 
			
		||||
        self._overlays = {}
 | 
			
		||||
 | 
			
		||||
        for line in output:
 | 
			
		||||
            match = overlay_re.match(line)
 | 
			
		||||
            if not match:
 | 
			
		||||
                continue
 | 
			
		||||
            self._overlays[match.group('key')] = match.group('name')
 | 
			
		||||
 | 
			
		||||
        return self._overlays
 | 
			
		||||
 | 
			
		||||
    @commit_on_success
 | 
			
		||||
    def scan(self, query=None):
 | 
			
		||||
        env = os.environ
 | 
			
		||||
        env['MY'] = "<category>/<name>-<version>:<slot> [<overlaynum>]\n"
 | 
			
		||||
 | 
			
		||||
	cmd = ['eix', '--format', '<availableversions:MY>', '--pure-packages', '-x']
 | 
			
		||||
	if query:
 | 
			
		||||
		cmd.extend(['--exact', query])
 | 
			
		||||
 | 
			
		||||
        if self.options['all']:
 | 
			
		||||
            if not self.options['quiet']:
 | 
			
		||||
                self.stdout.write('Killing existing versions...')
 | 
			
		||||
                self.stdout.flush()
 | 
			
		||||
            Version.objects.filter(packaged=True).update(alive=False)
 | 
			
		||||
            if not self.options['quiet']:
 | 
			
		||||
                self.stdout.write('done\n')
 | 
			
		||||
 | 
			
		||||
        output = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env).communicate()[0]
 | 
			
		||||
        output = output.strip().strip('\n')
 | 
			
		||||
 | 
			
		||||
        if len(output) == 0:
 | 
			
		||||
            if not query:
 | 
			
		||||
                return
 | 
			
		||||
            if self.options['purge-packages']:
 | 
			
		||||
                if not self.options['quiet']:
 | 
			
		||||
                    sys.stdout.write('- [p] %s\n' % (query))
 | 
			
		||||
                if '/' in query:
 | 
			
		||||
                    cat, pkg = portage.catsplit(query)
 | 
			
		||||
                    Package.objects.filter(category=cat, name=pkg).delete()
 | 
			
		||||
                else:
 | 
			
		||||
                    Package.objects.filter(name=query).delete()
 | 
			
		||||
            else:
 | 
			
		||||
                sys.stderr.write(self.style.ERROR("Unknown package '%s'\n" % query))
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
	output = output.split('\n')
 | 
			
		||||
        packages = {}
 | 
			
		||||
 | 
			
		||||
        line_re = re.compile(r'^(?P<cpv>.*?):(?P<slot>.*?) \[(?P<overlay>.*?)\]$')
 | 
			
		||||
 | 
			
		||||
        package = None
 | 
			
		||||
 | 
			
		||||
	for line in output:
 | 
			
		||||
            match = line_re.match(line)
 | 
			
		||||
 | 
			
		||||
            if not match:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            cpv = match.group('cpv')
 | 
			
		||||
            slot = match.group('slot')
 | 
			
		||||
            overlay = match.group('overlay')
 | 
			
		||||
 | 
			
		||||
            cat, pkg, ver, rev = portage.catpkgsplit(cpv)
 | 
			
		||||
 | 
			
		||||
            packages['%s/%s' % (cat, pkg)] = True
 | 
			
		||||
 | 
			
		||||
            if not package or not (cat == package.category and pkg == package.name):
 | 
			
		||||
                package = self.store_package(cat, pkg)
 | 
			
		||||
 | 
			
		||||
            self.store_version(package, cpv, slot, overlay)
 | 
			
		||||
 | 
			
		||||
        if self.options['purge-packages'] and not query:
 | 
			
		||||
            for package in Package.objects.all():
 | 
			
		||||
                cp = "%s/%s" % (package.category, package.name)
 | 
			
		||||
                if cp not in packages:
 | 
			
		||||
                    if not self.options['quiet']:
 | 
			
		||||
                        sys.stdout.write('- [p] %s\n' % (package))
 | 
			
		||||
                    package.delete()
 | 
			
		||||
 | 
			
		||||
    def store_package(self, cat, pkg):
 | 
			
		||||
        created = False
 | 
			
		||||
        obj = self.cache_get_package(cat, pkg)
 | 
			
		||||
 | 
			
		||||
        if not obj:
 | 
			
		||||
            obj, created = Package.objects.get_or_create(category=cat, name=pkg)
 | 
			
		||||
            self.cache_store_package(obj)
 | 
			
		||||
 | 
			
		||||
        if created:
 | 
			
		||||
            if not self.options['quiet']:
 | 
			
		||||
                sys.stdout.write('+ [p] %s/%s\n' % (cat, pkg))
 | 
			
		||||
 | 
			
		||||
        ' Set all versions dead, then set found versions alive and delete old versions '
 | 
			
		||||
        if not self.options['all']:
 | 
			
		||||
            Version.objects.filter(package=obj, packaged=True).update(alive=False)
 | 
			
		||||
 | 
			
		||||
        return obj
 | 
			
		||||
 | 
			
		||||
    def store_version(self, package, cpv, slot, overlay):
 | 
			
		||||
        cat, pkg, ver, rev = portage.catpkgsplit(cpv)
 | 
			
		||||
 | 
			
		||||
        overlays = self.overlays()
 | 
			
		||||
 | 
			
		||||
        if overlay in overlays:
 | 
			
		||||
            overlay = overlays[overlay]
 | 
			
		||||
        else:
 | 
			
		||||
            overlay = 'gentoo'
 | 
			
		||||
 | 
			
		||||
        created = False
 | 
			
		||||
        obj = self.cache_get_version(package.category, package.name, ver, rev, slot, overlay)
 | 
			
		||||
        if not obj:
 | 
			
		||||
            obj, created = Version.objects.get_or_create(package=package, slot=slot,
 | 
			
		||||
                                                         revision=rev, version=ver,
 | 
			
		||||
                                                         overlay=overlay)
 | 
			
		||||
 | 
			
		||||
        obj.alive = True
 | 
			
		||||
        obj.packaged = True
 | 
			
		||||
        obj.save()
 | 
			
		||||
 | 
			
		||||
        if created:
 | 
			
		||||
            self.cache_store_version(obj)
 | 
			
		||||
 | 
			
		||||
        ''' nothing to do (note: it can't be an upstream version because overlay can't be empty here) '''
 | 
			
		||||
        if not created:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        if not self.options['quiet']:
 | 
			
		||||
            sys.stdout.write('+ [v] %s \n' % (obj))
 | 
			
		||||
 | 
			
		||||
        if overlay == 'gentoo':
 | 
			
		||||
            package.n_packaged += 1
 | 
			
		||||
        else:
 | 
			
		||||
            package.n_overlay += 1
 | 
			
		||||
        package.n_versions += 1
 | 
			
		||||
        package.save()
 | 
			
		||||
 | 
			
		||||
        if self.options['no-log']:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        entry = VersionLog.objects.create(package=obj.package,
 | 
			
		||||
                                          action=VersionLog.VERSION_ADDED)
 | 
			
		||||
        entry.slot = obj.slot
 | 
			
		||||
        entry.revision = obj.revision
 | 
			
		||||
        entry.version = obj.version
 | 
			
		||||
        entry.overlay = obj.overlay
 | 
			
		||||
        entry.save()
 | 
			
		||||
 | 
			
		||||
    @commit_on_success
 | 
			
		||||
    def purge_versions(self, options):
 | 
			
		||||
        ' For each dead versions '
 | 
			
		||||
        for version in Version.objects.filter(packaged=True, alive=False):
 | 
			
		||||
            if version.overlay == 'gentoo':
 | 
			
		||||
                version.package.n_packaged -= 1
 | 
			
		||||
            else:
 | 
			
		||||
                version.package.n_overlay -= 1
 | 
			
		||||
            version.package.n_versions -= 1
 | 
			
		||||
            version.package.save()
 | 
			
		||||
 | 
			
		||||
            if not self.options['quiet']:
 | 
			
		||||
                sys.stdout.write('- [v] %s\n' % (version))
 | 
			
		||||
 | 
			
		||||
            if self.options['no-log']:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            entry = VersionLog.objects.create(package=version.package,
 | 
			
		||||
                                              action=VersionLog.VERSION_REMOVED)
 | 
			
		||||
            entry.slot = version.slot
 | 
			
		||||
            entry.revision = version.revision
 | 
			
		||||
            entry.version = version.version
 | 
			
		||||
            entry.overlay = version.overlay
 | 
			
		||||
            entry.save()
 | 
			
		||||
 | 
			
		||||
        Version.objects.filter(packaged=True, alive=False).delete()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										185
									
								
								euscanwww/djeuscan/management/commands/scan-upstream.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								euscanwww/djeuscan/management/commands/scan-upstream.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,185 @@
 | 
			
		||||
import subprocess
 | 
			
		||||
import portage
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
from StringIO import StringIO
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from portage import versions
 | 
			
		||||
from optparse import make_option
 | 
			
		||||
 | 
			
		||||
from django.db.transaction import commit_on_success
 | 
			
		||||
from django.core.management.base import BaseCommand, CommandError
 | 
			
		||||
from djeuscan.models import Package, Version, EuscanResult, VersionLog
 | 
			
		||||
 | 
			
		||||
class Command(BaseCommand):
 | 
			
		||||
    _overlays = {}
 | 
			
		||||
 | 
			
		||||
    option_list = BaseCommand.option_list + (
 | 
			
		||||
        make_option('--all',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='all',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Scan all packages'),
 | 
			
		||||
        make_option('--feed',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='feed',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Read euscan output from stdin'),
 | 
			
		||||
        make_option('--purge-versions',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='purge-versions',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Purge old versions'),
 | 
			
		||||
        make_option('--quiet',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='quiet',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Be quiet'),
 | 
			
		||||
        )
 | 
			
		||||
    args = '<package package ...>'
 | 
			
		||||
    help = 'Scans metadata and fills database'
 | 
			
		||||
 | 
			
		||||
    def handle(self, *args, **options):
 | 
			
		||||
        if options['feed']:
 | 
			
		||||
            self.parse_output(options, sys.stdin)
 | 
			
		||||
            if options['purge-versions']:
 | 
			
		||||
                self.purge_versions(options)
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        if not options['quiet']:
 | 
			
		||||
            self.stdout.write('Scanning upstream...\n')
 | 
			
		||||
 | 
			
		||||
        packages = []
 | 
			
		||||
 | 
			
		||||
        if options['all']:
 | 
			
		||||
            for pkg in Package.objects.all():
 | 
			
		||||
                packages.append('%s/%s' % (pkg.category, pkg.name))
 | 
			
		||||
        elif args:
 | 
			
		||||
            packages = list(args)
 | 
			
		||||
        else:
 | 
			
		||||
            packages = [ package[:-1] for package in sys.stdin.readlines() ]
 | 
			
		||||
 | 
			
		||||
        self.scan(options, packages)
 | 
			
		||||
 | 
			
		||||
        if options['purge-versions']:
 | 
			
		||||
            self.purge_versions(options)
 | 
			
		||||
 | 
			
		||||
        if not options['quiet']:
 | 
			
		||||
            self.stdout.write('Done.\n')
 | 
			
		||||
 | 
			
		||||
    def scan(self, options, packages=None):
 | 
			
		||||
        for package in packages:
 | 
			
		||||
            cmd = ['euscan', package]
 | 
			
		||||
 | 
			
		||||
            fp = subprocess.Popen(cmd, stdout=subprocess.PIPE)
 | 
			
		||||
            output = StringIO(fp.communicate()[0])
 | 
			
		||||
 | 
			
		||||
            self.parse_output(options, output)
 | 
			
		||||
 | 
			
		||||
    @commit_on_success
 | 
			
		||||
    def parse_output(self, options, output):
 | 
			
		||||
        from portage.versions import _cp
 | 
			
		||||
 | 
			
		||||
        package_re = re.compile(r'^ \* (?P<cpv>' + _cp + ') \[(?P<overlay>.*?)\]$')
 | 
			
		||||
        version_re = re.compile(r'^Upstream Version: (?P<ver>.*?) (?P<url>.*?)$')
 | 
			
		||||
 | 
			
		||||
        package = None
 | 
			
		||||
        log = ""
 | 
			
		||||
 | 
			
		||||
        while True:
 | 
			
		||||
            line = output.readline()
 | 
			
		||||
            if line == '':
 | 
			
		||||
                break
 | 
			
		||||
            match = package_re.match(line)
 | 
			
		||||
            if match:
 | 
			
		||||
                if package:
 | 
			
		||||
                    self.store_result(options, package, log)
 | 
			
		||||
 | 
			
		||||
                cpv = match.group('cpv')
 | 
			
		||||
                package = self.store_package(options, cpv)
 | 
			
		||||
                log = line
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            log += line
 | 
			
		||||
 | 
			
		||||
            match = version_re.match(line)
 | 
			
		||||
            if match:
 | 
			
		||||
                ver = match.group('ver')
 | 
			
		||||
                url = match.group('url')
 | 
			
		||||
                self.store_version(options, package, ver, url)
 | 
			
		||||
 | 
			
		||||
        if package:
 | 
			
		||||
            self.store_result(options, package, log)
 | 
			
		||||
 | 
			
		||||
    def store_result(self, options, package, log):
 | 
			
		||||
        # Remove previous logs
 | 
			
		||||
        EuscanResult.objects.filter(package=package).delete()
 | 
			
		||||
 | 
			
		||||
        obj = EuscanResult()
 | 
			
		||||
        obj.package = package
 | 
			
		||||
        obj.result = log
 | 
			
		||||
        obj.datetime = datetime.now()
 | 
			
		||||
        obj.save()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def store_package(self, options, cpv):
 | 
			
		||||
        cat, pkg, ver, rev = portage.catpkgsplit(cpv)
 | 
			
		||||
 | 
			
		||||
        obj, created = Package.objects.get_or_create(category=cat, name=pkg)
 | 
			
		||||
 | 
			
		||||
        if created and not options['quiet']:
 | 
			
		||||
            sys.stdout.write('+ [p] %s/%s\n' % (cat, pkg))
 | 
			
		||||
 | 
			
		||||
        ' Set all versions dead, then set found versions alive and delete old versions '
 | 
			
		||||
        Version.objects.filter(package=obj, packaged=False).update(alive=False)
 | 
			
		||||
 | 
			
		||||
        return obj
 | 
			
		||||
 | 
			
		||||
    def store_version(self, options, package, ver, url):
 | 
			
		||||
        obj, created = Version.objects.get_or_create(package=package, slot='',
 | 
			
		||||
                                                     revision='r0', version=ver,
 | 
			
		||||
                                                     overlay='')
 | 
			
		||||
 | 
			
		||||
        obj.alive = True
 | 
			
		||||
        obj.urls = url
 | 
			
		||||
        obj.packaged = False
 | 
			
		||||
        obj.save()
 | 
			
		||||
 | 
			
		||||
        ''' If it's not a new version, just update the object and continue '''
 | 
			
		||||
        if not created:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        if not options['quiet']:
 | 
			
		||||
            sys.stdout.write('+ [u] %s %s\n' % (obj, url))
 | 
			
		||||
 | 
			
		||||
        entry = VersionLog.objects.create(package=package, action=VersionLog.VERSION_ADDED)
 | 
			
		||||
        entry.slot = ''
 | 
			
		||||
        entry.revision = 'r0'
 | 
			
		||||
        entry.version = ver
 | 
			
		||||
        entry.overlay = ''
 | 
			
		||||
        entry.save()
 | 
			
		||||
 | 
			
		||||
        package.n_versions += 1
 | 
			
		||||
        package.save()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @commit_on_success
 | 
			
		||||
    def purge_versions(self, options):
 | 
			
		||||
        ' For each dead versions '
 | 
			
		||||
        for version in Version.objects.filter(packaged=False, alive=False):
 | 
			
		||||
            entry = VersionLog.objects.create(package=version.package, action=VersionLog.VERSION_REMOVED)
 | 
			
		||||
            entry.slot = version.slot
 | 
			
		||||
            entry.revision = version.revision
 | 
			
		||||
            entry.version = version.version
 | 
			
		||||
            entry.overlay = version.overlay
 | 
			
		||||
            entry.save()
 | 
			
		||||
 | 
			
		||||
            version.package.n_versions -= 1
 | 
			
		||||
            version.package.save()
 | 
			
		||||
 | 
			
		||||
            if not options['quiet']:
 | 
			
		||||
                sys.stdout.write('- [u] %s %s\n' % (version, version.urls))
 | 
			
		||||
        Version.objects.filter(packaged=False, alive=False).delete()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										185
									
								
								euscanwww/djeuscan/management/commands/update-counters.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								euscanwww/djeuscan/management/commands/update-counters.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,185 @@
 | 
			
		||||
import datetime
 | 
			
		||||
 | 
			
		||||
from optparse import make_option
 | 
			
		||||
 | 
			
		||||
from django.db.models import Count, Sum
 | 
			
		||||
from django.db.transaction import commit_on_success
 | 
			
		||||
from django.core.management.base import BaseCommand, CommandError
 | 
			
		||||
 | 
			
		||||
from djeuscan.models import Package, Herd, Maintainer, Version
 | 
			
		||||
from djeuscan.models import HerdLog, MaintainerLog, CategoryLog, WorldLog
 | 
			
		||||
from djeuscan import charts
 | 
			
		||||
 | 
			
		||||
from distutils.version import StrictVersion, LooseVersion
 | 
			
		||||
 | 
			
		||||
def compare_versions(version1, version2):
 | 
			
		||||
    try:
 | 
			
		||||
        return cmp(StrictVersion(version1), StrictVersion(version2))
 | 
			
		||||
    # in case of abnormal version number, fall back to LooseVersion
 | 
			
		||||
    except ValueError:
 | 
			
		||||
        return cmp(LooseVersion(version1), LooseVersion(version2))
 | 
			
		||||
 | 
			
		||||
class Command(BaseCommand):
 | 
			
		||||
    _overlays = {}
 | 
			
		||||
    help = 'Update counters'
 | 
			
		||||
 | 
			
		||||
    option_list = BaseCommand.option_list + (
 | 
			
		||||
        make_option('--quiet',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='quiet',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Be quiet'),
 | 
			
		||||
        make_option('--fast',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='fast',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Skip sanity checks'),
 | 
			
		||||
        make_option('--nolog',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            dest='nolog',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='Skip logs'),
 | 
			
		||||
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @commit_on_success
 | 
			
		||||
    def handle(self, *args, **options):
 | 
			
		||||
        now = datetime.datetime.now()
 | 
			
		||||
 | 
			
		||||
        categories = {}
 | 
			
		||||
        herds = {}
 | 
			
		||||
        maintainers = {}
 | 
			
		||||
 | 
			
		||||
        wlog = None
 | 
			
		||||
 | 
			
		||||
        if not options['nolog']:
 | 
			
		||||
            wlog = WorldLog()
 | 
			
		||||
            wlog.datetime = now
 | 
			
		||||
 | 
			
		||||
            for cat in Package.objects.values('category').distinct():
 | 
			
		||||
                clog = CategoryLog()
 | 
			
		||||
                clog.datetime = now
 | 
			
		||||
                clog.category = cat['category']
 | 
			
		||||
                categories[clog.category] = clog
 | 
			
		||||
 | 
			
		||||
            for herd in Herd.objects.all():
 | 
			
		||||
                hlog = HerdLog()
 | 
			
		||||
                hlog.datetime = now
 | 
			
		||||
                hlog.herd = herd
 | 
			
		||||
                herds[herd.id] = hlog
 | 
			
		||||
 | 
			
		||||
            for maintainer in Maintainer.objects.all():
 | 
			
		||||
                mlog = MaintainerLog()
 | 
			
		||||
                mlog.datetime = now
 | 
			
		||||
                mlog.maintainer = maintainer
 | 
			
		||||
                maintainers[maintainer.id] = mlog
 | 
			
		||||
 | 
			
		||||
        package_queryset = Package.objects.all()
 | 
			
		||||
 | 
			
		||||
        n_versions = {}
 | 
			
		||||
        n_packaged = {}
 | 
			
		||||
        n_overlay = {}
 | 
			
		||||
 | 
			
		||||
        last_versions_gentoo = {}
 | 
			
		||||
        last_versions_overlay = {}
 | 
			
		||||
        last_versions_upstream = {}
 | 
			
		||||
 | 
			
		||||
        def add_safe(storage, key):
 | 
			
		||||
            if key not in storage:
 | 
			
		||||
                storage[key] = 1
 | 
			
		||||
            else:
 | 
			
		||||
                storage[key] += 1
 | 
			
		||||
 | 
			
		||||
        def add_last_ver(storage, version):
 | 
			
		||||
            key = version['package_id']
 | 
			
		||||
            if key not in storage:
 | 
			
		||||
                storage[key] = version
 | 
			
		||||
                return
 | 
			
		||||
            if version['version'].startswith('9999'):
 | 
			
		||||
                return
 | 
			
		||||
            if compare_versions(storage[key]['version'], version['version']) < 0:
 | 
			
		||||
                storage[key] = version
 | 
			
		||||
 | 
			
		||||
        if not options['fast']:
 | 
			
		||||
            attrs = ['id', 'version', 'overlay', 'packaged', 'package_id']
 | 
			
		||||
            for version in Version.objects.all().values(*attrs):
 | 
			
		||||
                overlay, packaged = version['overlay'], version['packaged']
 | 
			
		||||
                package_id = version['package_id']
 | 
			
		||||
 | 
			
		||||
                add_safe(n_versions, package_id)
 | 
			
		||||
 | 
			
		||||
                if not packaged:
 | 
			
		||||
                    add_last_ver(last_versions_upstream, version)
 | 
			
		||||
                    continue
 | 
			
		||||
                if overlay == 'gentoo':
 | 
			
		||||
                    add_safe(n_packaged, package_id)
 | 
			
		||||
                    add_last_ver(last_versions_gentoo, version)
 | 
			
		||||
                else:
 | 
			
		||||
                    add_safe(n_overlay, package_id)
 | 
			
		||||
                    add_last_ver(last_versions_overlay, version)
 | 
			
		||||
 | 
			
		||||
        for package in package_queryset.select_related('herds', 'maintainers'):
 | 
			
		||||
            if not options['fast']:
 | 
			
		||||
                package.n_versions = n_versions.get(package.id, 0)
 | 
			
		||||
                package.n_packaged = n_packaged.get(package.id, 0)
 | 
			
		||||
                package.n_overlay = n_overlay.get(package.id, 0)
 | 
			
		||||
 | 
			
		||||
                default = {'id' : None}
 | 
			
		||||
                package.last_version_gentoo_id = last_versions_gentoo.get(package.id, default)['id']
 | 
			
		||||
                package.last_version_overlay_id = last_versions_overlay.get(package.id, default)['id']
 | 
			
		||||
                package.last_version_upstream_id = last_versions_upstream.get(package.id, default)['id']
 | 
			
		||||
 | 
			
		||||
                package.save()
 | 
			
		||||
 | 
			
		||||
            n_packages_gentoo = int(package.n_packaged == package.n_versions)
 | 
			
		||||
            n_packages_overlay = int(package.n_overlay and package.n_packaged + package.n_overlay == package.n_versions)
 | 
			
		||||
            n_packages_outdated = int(package.n_packaged + package.n_overlay < package.n_versions)
 | 
			
		||||
 | 
			
		||||
            def update_row(storage, key):
 | 
			
		||||
                storage[key].n_packages_gentoo   += n_packages_gentoo
 | 
			
		||||
                storage[key].n_packages_overlay  += n_packages_overlay
 | 
			
		||||
                storage[key].n_packages_outdated += n_packages_outdated
 | 
			
		||||
 | 
			
		||||
                storage[key].n_versions_gentoo   += package.n_packaged
 | 
			
		||||
                storage[key].n_versions_overlay  += package.n_overlay
 | 
			
		||||
                storage[key].n_versions_upstream += package.n_versions - package.n_packaged - package.n_overlay
 | 
			
		||||
            def update_log(storage, qs):
 | 
			
		||||
                for row in qs:
 | 
			
		||||
                    update_row(storage, row['id'])
 | 
			
		||||
 | 
			
		||||
            if not options['nolog']:
 | 
			
		||||
                update_log(herds, package.herds.all().values('id'))
 | 
			
		||||
                update_log(maintainers, package.maintainers.all().values('id'))
 | 
			
		||||
                update_row(categories, package.category)
 | 
			
		||||
 | 
			
		||||
                wlog.n_packages_gentoo   += n_packages_gentoo
 | 
			
		||||
                wlog.n_packages_overlay  += n_packages_overlay
 | 
			
		||||
                wlog.n_packages_outdated += n_packages_outdated
 | 
			
		||||
 | 
			
		||||
                wlog.n_versions_gentoo   += package.n_packaged
 | 
			
		||||
                wlog.n_versions_overlay  += package.n_overlay
 | 
			
		||||
                wlog.n_versions_upstream += package.n_versions - package.n_packaged - package.n_overlay
 | 
			
		||||
 | 
			
		||||
        if options['nolog']:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        for clog in categories.values():
 | 
			
		||||
            if not options['quiet']:
 | 
			
		||||
                self.stdout.write('+ [cl] %s\n' % clog)
 | 
			
		||||
            charts.rrd_update('category-%s' % clog.category, now, clog)
 | 
			
		||||
            clog.save()
 | 
			
		||||
 | 
			
		||||
        for hlog in herds.values():
 | 
			
		||||
            if not options['quiet']:
 | 
			
		||||
                self.stdout.write('+ [hl] %s\n' % hlog)
 | 
			
		||||
            charts.rrd_update('herd-%d' % hlog.herd.id, now, hlog)
 | 
			
		||||
            hlog.save()
 | 
			
		||||
 | 
			
		||||
        for mlog in maintainers.values():
 | 
			
		||||
            if not options['quiet']:
 | 
			
		||||
                self.stdout.write('+ [ml] %s\n' % mlog)
 | 
			
		||||
            charts.rrd_update('maintainer-%d' % mlog.maintainer.id, now, mlog)
 | 
			
		||||
            mlog.save()
 | 
			
		||||
 | 
			
		||||
        charts.rrd_update('world', now, wlog)
 | 
			
		||||
        wlog.save()
 | 
			
		||||
							
								
								
									
										0
									
								
								euscanwww/djeuscan/management/commands/utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								euscanwww/djeuscan/management/commands/utils.py
									
									
									
									
									
										Normal file
									
								
							
		Reference in New Issue
	
	Block a user