140 lines
3.8 KiB
Python
140 lines
3.8 KiB
Python
|
import portage
|
||
|
import sys
|
||
|
|
||
|
from django.utils import timezone
|
||
|
from django.db.transaction import commit_on_success
|
||
|
|
||
|
from euscan import CONFIG, output
|
||
|
from euscan.scan import scan_upstream as euscan_scan_upstream
|
||
|
|
||
|
from djeuscan.models import Package, Version, EuscanResult, VersionLog
|
||
|
|
||
|
|
||
|
class ScanUpstream(object):
|
||
|
def __init__(self, quiet=False):
|
||
|
self.quiet = quiet
|
||
|
|
||
|
def scan(self, package):
|
||
|
CONFIG["format"] = "dict"
|
||
|
output.set_query(package)
|
||
|
|
||
|
euscan_scan_upstream(package)
|
||
|
|
||
|
out = output.get_formatted_output()
|
||
|
out_json = output.get_formatted_output("json")
|
||
|
|
||
|
try:
|
||
|
cpv = out[package]["metadata"]["cpv"]
|
||
|
except KeyError:
|
||
|
return {}
|
||
|
|
||
|
obj = self.store_package(cpv)
|
||
|
|
||
|
for res in out[package]["result"]:
|
||
|
self.store_version(obj, res["version"], " ".join(res["urls"]))
|
||
|
|
||
|
self.store_result(obj, out_json)
|
||
|
|
||
|
return out
|
||
|
|
||
|
def store_result(self, package, log):
|
||
|
# Remove previous logs
|
||
|
EuscanResult.objects.filter(package=package).delete()
|
||
|
|
||
|
obj = EuscanResult()
|
||
|
obj.package = package
|
||
|
obj.result = log
|
||
|
obj.datetime = timezone.now()
|
||
|
obj.save()
|
||
|
|
||
|
def store_package(self, cpv):
|
||
|
cat, pkg, ver, rev = portage.catpkgsplit(cpv)
|
||
|
|
||
|
obj, created = Package.objects.get_or_create(category=cat, name=pkg)
|
||
|
|
||
|
if created and not self.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, package, ver, url):
|
||
|
obj, created = Version.objects.get_or_create(
|
||
|
package=package, slot='', revision='r0', version=ver, overlay='',
|
||
|
defaults={"alive": True, "urls": url, "packaged": False}
|
||
|
)
|
||
|
if not created:
|
||
|
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 self.quiet:
|
||
|
sys.stdout.write('+ [u] %s %s\n' % (obj, url))
|
||
|
|
||
|
VersionLog.objects.create(
|
||
|
package=package,
|
||
|
action=VersionLog.VERSION_ADDED,
|
||
|
slot='',
|
||
|
revision='r0',
|
||
|
version=ver,
|
||
|
overlay=''
|
||
|
)
|
||
|
|
||
|
package.n_versions += 1
|
||
|
package.save()
|
||
|
|
||
|
|
||
|
@commit_on_success
|
||
|
def purge_versions(quiet=False):
|
||
|
# For each dead versions
|
||
|
for version in Version.objects.filter(packaged=False, alive=False):
|
||
|
VersionLog.objects.create(
|
||
|
package=version.package,
|
||
|
action=VersionLog.VERSION_REMOVED,
|
||
|
slot=version.slot,
|
||
|
revision=version.revision,
|
||
|
version=version.version,
|
||
|
overlay=version.overlay
|
||
|
)
|
||
|
|
||
|
version.package.n_versions -= 1
|
||
|
version.package.save()
|
||
|
|
||
|
if not quiet:
|
||
|
sys.stdout.write('- [u] %s %s\n' % (version, version.urls))
|
||
|
Version.objects.filter(packaged=False, alive=False).delete()
|
||
|
|
||
|
|
||
|
def scan_upstream(packages=None, purge_versions=False, quiet=False,
|
||
|
logger=None, stdout=None):
|
||
|
|
||
|
stdout = sys.stdout if stdout is None else stdout
|
||
|
|
||
|
scan_handler = ScanUpstream(quiet)
|
||
|
|
||
|
if not quiet:
|
||
|
stdout.write('Scanning upstream...\n')
|
||
|
|
||
|
if packages is None:
|
||
|
packages = Package.objects.all()
|
||
|
|
||
|
for pkg in packages:
|
||
|
if isinstance(pkg, Package):
|
||
|
scan_handler.scan('%s/%s' % (pkg.category, pkg.name))
|
||
|
else:
|
||
|
scan_handler.scan(pkg)
|
||
|
|
||
|
if purge_versions:
|
||
|
purge_versions(quiet)
|
||
|
|
||
|
if not quiet:
|
||
|
stdout.write('Done.\n')
|