euscanwww/scan_portage: fixes and add --category
Signed-off-by: Corentin Chary <corentin.chary@gmail.com>
This commit is contained in:
parent
ad5e399096
commit
093cb4da47
@ -19,6 +19,11 @@ class Command(BaseCommand):
|
|||||||
dest='all',
|
dest='all',
|
||||||
default=False,
|
default=False,
|
||||||
help='Scan all packages'),
|
help='Scan all packages'),
|
||||||
|
make_option('--category',
|
||||||
|
action='store',
|
||||||
|
dest='category',
|
||||||
|
default=None,
|
||||||
|
help='Scan only this category'),
|
||||||
make_option('--purge-packages',
|
make_option('--purge-packages',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='purge-packages',
|
dest='purge-packages',
|
||||||
@ -47,7 +52,7 @@ class Command(BaseCommand):
|
|||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
set_verbosity_level(logger, options.get("verbosity", 1))
|
set_verbosity_level(logger, options.get("verbosity", 1))
|
||||||
|
|
||||||
if options['all']:
|
if options['all'] or options['category']:
|
||||||
packages = None
|
packages = None
|
||||||
elif len(args):
|
elif len(args):
|
||||||
packages = [pkg for pkg in args]
|
packages = [pkg for pkg in args]
|
||||||
@ -56,6 +61,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
scan_portage(
|
scan_portage(
|
||||||
packages=packages,
|
packages=packages,
|
||||||
|
category=options['category'],
|
||||||
no_log=options["no-log"],
|
no_log=options["no-log"],
|
||||||
purge_packages=options["purge-packages"],
|
purge_packages=options["purge-packages"],
|
||||||
purge_versions=options["purge-versions"],
|
purge_versions=options["purge-versions"],
|
||||||
|
@ -56,11 +56,78 @@ class ScanPortage(object):
|
|||||||
)
|
)
|
||||||
self._cache['versions'][key] = version
|
self._cache['versions'][key] = version
|
||||||
|
|
||||||
def scan(self, query=None):
|
def scan_eix_xml(self, query, category=None):
|
||||||
cmd = ['eix', '--xml']
|
cmd = ['eix', '--xml']
|
||||||
if query:
|
if query:
|
||||||
cmd.extend(['--exact', query])
|
cmd.extend(['--exact', query])
|
||||||
|
if category:
|
||||||
|
cmd.extend(['-C', category])
|
||||||
|
|
||||||
|
sub = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||||
|
output = sub.stdout
|
||||||
|
|
||||||
|
try:
|
||||||
|
parser = iterparse(output, ["start", "end"])
|
||||||
|
parser.next() # read root tag just for testing output
|
||||||
|
except ParseError:
|
||||||
|
if query:
|
||||||
|
msg = "Unknown package '%s'" % query
|
||||||
|
else:
|
||||||
|
msg = "No packages."
|
||||||
|
self.logger.error(self.style.ERROR(msg))
|
||||||
|
return
|
||||||
|
|
||||||
|
package = {'versions' : []}
|
||||||
|
category = ""
|
||||||
|
|
||||||
|
for event, elem in parser:
|
||||||
|
if event == "start": # on tag opening
|
||||||
|
if elem.tag == "category":
|
||||||
|
category = elem.attrib["name"]
|
||||||
|
elif elem.tag == "package":
|
||||||
|
package["package"] = elem.attrib["name"]
|
||||||
|
package["category"] = category
|
||||||
|
elif elem.tag in ["description", "homepage"]:
|
||||||
|
package[elem.tag] = elem.text or ""
|
||||||
|
elif elem.tag == "version":
|
||||||
|
# append version data to versions
|
||||||
|
cpv = "%s/%s-%s" % \
|
||||||
|
(package["category"], package["package"], elem.attrib["id"])
|
||||||
|
slot = elem.attrib.get("slot", "")
|
||||||
|
overlay = elem.attrib.get("repository", "gentoo")
|
||||||
|
package["versions"].append((cpv, slot, overlay))
|
||||||
|
|
||||||
|
elif event == "end": # on tag closing
|
||||||
|
if elem.tag == "package":
|
||||||
|
# clean old data
|
||||||
|
yield package
|
||||||
|
package = {"versions" : []}
|
||||||
|
|
||||||
|
if elem.tag == "category":
|
||||||
|
# clean old data
|
||||||
|
category = ""
|
||||||
|
elem.clear()
|
||||||
|
|
||||||
|
def prepare_purge_versions(self, packages, query=None, category=None):
|
||||||
|
if not self.purge_versions:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Set all versions dead, then set found versions alive and
|
||||||
|
# delete old versions
|
||||||
|
if not query:
|
||||||
|
# Optimisation for --all or --category
|
||||||
|
self.logger.info('Killing existing versions...')
|
||||||
|
qs = Version.objects.filter(packaged=True)
|
||||||
|
if category:
|
||||||
|
qs.filter(package__category=category)
|
||||||
|
qs.update(alive=False)
|
||||||
|
self.logger.info('done')
|
||||||
|
else:
|
||||||
|
for package in packages:
|
||||||
|
Version.objects.filter(package=package, packaged=True).\
|
||||||
|
update(alive=False)
|
||||||
|
|
||||||
|
def scan(self, query=None, category=None):
|
||||||
if not query:
|
if not query:
|
||||||
current_packages = Package.objects.all()
|
current_packages = Package.objects.all()
|
||||||
elif '/' in query:
|
elif '/' in query:
|
||||||
@ -68,78 +135,22 @@ class ScanPortage(object):
|
|||||||
current_packages = Package.objects.filter(category=cat, name=pkg)
|
current_packages = Package.objects.filter(category=cat, name=pkg)
|
||||||
else:
|
else:
|
||||||
current_packages = Package.objects.filter(name=query)
|
current_packages = Package.objects.filter(name=query)
|
||||||
|
if category:
|
||||||
|
current_packages = current_packages.filter(category=category)
|
||||||
|
|
||||||
if self.purge_versions:
|
self.prepare_purge_versions(current_packages, query, category)
|
||||||
if not query:
|
|
||||||
self.logger.info('Killing existing versions...')
|
|
||||||
Version.objects.filter(packaged=True).update(alive=False)
|
|
||||||
self.logger.info('done')
|
|
||||||
else:
|
|
||||||
for package in current_packages:
|
|
||||||
Version.objects.filter(package=package, packaged=True).\
|
|
||||||
update(alive=False)
|
|
||||||
|
|
||||||
sub = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
|
||||||
|
|
||||||
output = sub.stdout
|
|
||||||
|
|
||||||
try:
|
|
||||||
parser = iterparse(output, ["start", "end"])
|
|
||||||
parser.next() # read root tag just for testing output
|
|
||||||
except ParseError:
|
|
||||||
self.logger.error(
|
|
||||||
self.style.ERROR(
|
|
||||||
"Unknown package '%s'" % query
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
cat, pkg, homepage, desc = ("", "", "", "")
|
|
||||||
versions = []
|
|
||||||
packages_alive = set()
|
packages_alive = set()
|
||||||
|
|
||||||
for event, elem in parser:
|
for data in self.scan_eix_xml(query, category):
|
||||||
if event == "start": # on tag opening
|
cat, pkg = data['category'], data['package']
|
||||||
if elem.tag == "category":
|
package = self.store_package(cat, pkg, data['homepage'], data['description'])
|
||||||
cat = elem.attrib["name"]
|
packages_alive.add("%s/%s" % (cat, pkg))
|
||||||
if elem.tag == "package":
|
for cpv, slot, overlay in data['versions']:
|
||||||
pkg = elem.attrib["name"]
|
|
||||||
if elem.tag == "description":
|
|
||||||
desc = elem.text or ""
|
|
||||||
if elem.tag == "homepage":
|
|
||||||
homepage = elem.text or ""
|
|
||||||
if elem.tag == "version":
|
|
||||||
# append version data to versions
|
|
||||||
cpv = "%s/%s-%s" % (cat, pkg, elem.attrib["id"])
|
|
||||||
slot = elem.attrib.get("slot", "")
|
|
||||||
overlay = elem.attrib.get("overlay", "")
|
|
||||||
versions.append((cpv, slot, overlay))
|
|
||||||
|
|
||||||
elif event == "end": # on tag closing
|
|
||||||
if elem.tag == "package":
|
|
||||||
# package tag has been closed, saving everything!
|
|
||||||
package = self.store_package(cat, pkg, homepage,
|
|
||||||
desc)
|
|
||||||
packages_alive.add('%s/%s' % (cat, pkg))
|
|
||||||
for cpv, slot, overlay in versions:
|
|
||||||
self.store_version(package, cpv, slot, overlay)
|
self.store_version(package, cpv, slot, overlay)
|
||||||
|
|
||||||
# clean old data
|
self.purge_old_packages(current_packages, packages_alive)
|
||||||
pkg, homepage, desc = ("", "", "")
|
self.purge_old_versions()
|
||||||
versions = []
|
|
||||||
|
|
||||||
if elem.tag == "category":
|
|
||||||
# clean old data
|
|
||||||
cat = ""
|
|
||||||
elem.clear()
|
|
||||||
|
|
||||||
if self.purge_packages:
|
|
||||||
for package in current_packages:
|
|
||||||
cp = "%s/%s" % (package.category, package.name)
|
|
||||||
if cp not in packages_alive:
|
|
||||||
self.logger.info('- [p] %s' % (package))
|
|
||||||
package.delete()
|
|
||||||
if self.purge_versions:
|
|
||||||
self.purge_old_versions(current_packages)
|
|
||||||
|
|
||||||
def store_package(self, cat, pkg, homepage, description):
|
def store_package(self, cat, pkg, homepage, description):
|
||||||
created = False
|
created = False
|
||||||
@ -157,14 +168,6 @@ class ScanPortage(object):
|
|||||||
if created:
|
if created:
|
||||||
self.logger.info('+ [p] %s/%s' % (cat, pkg))
|
self.logger.info('+ [p] %s/%s' % (cat, pkg))
|
||||||
|
|
||||||
# Set all versions dead, then set found versions alive and
|
|
||||||
# delete old versions
|
|
||||||
if not self.purge_versions:
|
|
||||||
Version.objects.filter(
|
|
||||||
package=obj,
|
|
||||||
packaged=True
|
|
||||||
).update(alive=False)
|
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def store_version(self, package, cpv, slot, overlay):
|
def store_version(self, package, cpv, slot, overlay):
|
||||||
@ -223,18 +226,21 @@ class ScanPortage(object):
|
|||||||
overlay=obj.overlay
|
overlay=obj.overlay
|
||||||
)
|
)
|
||||||
|
|
||||||
def purge_old_versions(self, packages):
|
def purge_old_packages(self, packages, alive):
|
||||||
# For each dead versions
|
if not self.purge_packages:
|
||||||
if packages:
|
return
|
||||||
versions = []
|
|
||||||
for package in packages:
|
|
||||||
qs = Version.objects.filter(package=package, packaged=True,
|
|
||||||
alive=False)
|
|
||||||
for version in qs:
|
|
||||||
versions.append(version)
|
|
||||||
else:
|
|
||||||
versions = Version.objects.filter(packaged=True, alive=False)
|
|
||||||
|
|
||||||
|
for package in packages:
|
||||||
|
cp = "%s/%s" % (package.category, package.name)
|
||||||
|
if cp not in alive:
|
||||||
|
self.logger.info('- [p] %s' % (package))
|
||||||
|
package.delete()
|
||||||
|
|
||||||
|
def purge_old_versions(self):
|
||||||
|
if not self.purge_versions:
|
||||||
|
return
|
||||||
|
|
||||||
|
versions = Version.objects.filter(packaged=True, alive=False)
|
||||||
for version in versions:
|
for version in versions:
|
||||||
if version.overlay == 'gentoo':
|
if version.overlay == 'gentoo':
|
||||||
version.package.n_packaged -= 1
|
version.package.n_packaged -= 1
|
||||||
@ -257,11 +263,11 @@ class ScanPortage(object):
|
|||||||
overlay=version.overlay
|
overlay=version.overlay
|
||||||
)
|
)
|
||||||
|
|
||||||
Version.objects.filter(packaged=True, alive=False).delete()
|
versions.delete()
|
||||||
|
|
||||||
|
|
||||||
@commit_on_success
|
@commit_on_success
|
||||||
def scan_portage(packages=None, no_log=False, purge_packages=False,
|
def scan_portage(packages=None, category=None, no_log=False, purge_packages=False,
|
||||||
purge_versions=False, prefetch=False, logger=None):
|
purge_versions=False, prefetch=False, logger=None):
|
||||||
|
|
||||||
logger = logger or FakeLogger()
|
logger = logger or FakeLogger()
|
||||||
@ -287,7 +293,7 @@ def scan_portage(packages=None, no_log=False, purge_packages=False,
|
|||||||
logger.info('done')
|
logger.info('done')
|
||||||
|
|
||||||
if not packages:
|
if not packages:
|
||||||
scan_handler.scan()
|
scan_handler.scan(category=category)
|
||||||
else:
|
else:
|
||||||
for pkg in packages:
|
for pkg in packages:
|
||||||
if isinstance(pkg, Package):
|
if isinstance(pkg, Package):
|
||||||
|
Loading…
Reference in New Issue
Block a user