[Yum-devel] [PATCH 3/3] pkgtags db - searching
Seth Vidal
skvidal at fedoraproject.org
Fri Feb 5 22:42:04 UTC 2010
this patch adds the pkgtags metatadata and the integrates it into our
search mechanism. Completely optional repodata format.
Also adds a decompress() function from yum.misc that allows for us
to pass files to it and not care what compression mechanism they are using
it's a bit simplistic at the moment but can easily be enhanced.
---
yum/__init__.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
yum/misc.py | 25 +++++++++++++++++++
yum/repos.py | 2 +-
3 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/yum/__init__.py b/yum/__init__.py
index 083b445..8b69788 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -44,6 +44,7 @@ import rpmUtils.updates
from rpmUtils.arch import canCoinstall, ArchStorage, isMultiLibArch
import rpmUtils.transaction
import comps
+import pkgtag_db
from repos import RepoStorage
import misc
from parser import ConfigPreProcessor, varReplace
@@ -144,6 +145,7 @@ class YumBase(depsolve.Depsolve):
self._history = None
self._pkgSack = None
self._lockfile = None
+ self._tags = None
self.skipped_packages = [] # packages skip by the skip-broken code
self.logger = logging.getLogger("yum.YumBase")
self.verbose_logger = logging.getLogger("yum.verbose.YumBase")
@@ -719,6 +721,38 @@ class YumBase(depsolve.Depsolve):
self.verbose_logger.debug('group time: %0.3f' % (time.time() - group_st))
return self._comps
+ def _getTags(self):
+ """ create the tags object used to search/report from the pkgtags
+ metadata"""
+
+ tag_st = time.time()
+ self.verbose_logger.log(logginglevels.DEBUG_4,
+ _('Getting pkgtags metadata'))
+
+ if self._tags is None:
+ self._tags = yum.pkgtag_db.PackageTags()
+
+ for repo in self.repos.listEnabled():
+ if 'pkgtags' not in repo.repoXML.fileTypes():
+ continue
+
+ self.verbose_logger.log(logginglevels.DEBUG_4,
+ _('Adding tags from repository: %s'), repo)
+
+ # fetch the sqlite tagdb
+ try:
+ tag_md = repo.retrieveMD('pkgtags')
+ tag_sqlite = yum.misc.decompress(tag_md)
+ # feed it into _tags.add()
+ self._tags.add(repo.id, tag_sqlite)
+ except (Errors.RepoError, Errors.PkgTagsError), e:
+ msg = _('Failed to add Pkg Tags for repository: %s - %s') % (repo, str(e))
+ self.logger.critical(msg)
+
+
+ self.verbose_logger.debug('tags time: %0.3f' % (time.time() - tag_st))
+ return self._tags
+
def _getHistory(self):
"""auto create the history object that to access/append the transaction
history information. """
@@ -764,6 +798,11 @@ class YumBase(depsolve.Depsolve):
fset=lambda self, value: setattr(self, "_history",value),
fdel=lambda self: setattr(self, "_history", None),
doc="Yum History Object")
+
+ pkgtags = property(fget=lambda self: self._getTags(),
+ fset=lambda self, value: setattr(self, "_tags",value),
+ fdel=lambda self: setattr(self, "_tags", None),
+ doc="Yum Package Tags Object")
def doSackFilelistPopulate(self):
@@ -2076,6 +2115,22 @@ class YumBase(depsolve.Depsolve):
results2sorted_lists(tmpres, sorted_lists)
del tmpres
+ tmpres = self.searchPackageTags(real_crit_lower)
+ for pkg in tmpres:
+ count = 0
+ matchkeys = []
+ tagresults = []
+ for (match, taglist) in tmpres[pkg]:
+ count += len(taglist)
+ matchkeys.append(rcl2c[match])
+ tagresults.extend(taglist)
+
+
+ if count not in sorted_lists: sorted_lists[count] = []
+ sorted_lists[count].append((pkg, matchkeys, tagresults))
+
+ del tmpres
+
# By default just sort using package sorting
sort_func = operator.itemgetter(0)
if keys:
@@ -2097,7 +2152,22 @@ class YumBase(depsolve.Depsolve):
if not showdups:
yielded[(po.name, po.arch)] = 1
-
+ def searchPackageTags(self, criteria):
+ results = {} # name = [(criteria, taglist)]
+ for c in criteria:
+ c = c.lower()
+ res = self.pkgtags.search_tags(c)
+ for (name, taglist) in res.items():
+ pkgs = self.pkgSack.searchNevra(name=name)
+ if not pkgs:
+ continue
+ pkg = pkgs[0]
+ if pkg not in results:
+ results[pkg] = []
+ results[pkg].append((c, taglist))
+
+ return results
+
def searchPackages(self, fields, criteria, callback=None):
"""Search specified fields for matches to criteria
optional callback specified to print out results
diff --git a/yum/misc.py b/yum/misc.py
index 4b0226b..d63993b 100644
--- a/yum/misc.py
+++ b/yum/misc.py
@@ -17,6 +17,7 @@ import glob
import pwd
import fnmatch
import bz2
+import gzip
from stat import *
try:
import gpgme
@@ -945,3 +946,27 @@ def get_uuid(savepath):
return myid
+def decompress(filename):
+ """take a filename and decompress it into the same relative location.
+ if the file is not compressed just return the file"""
+ out = filename
+ if filename.endswith('.gz'):
+ out = filename.replace('.gz', '')
+ decom = gzip.open(filename)
+ fo = open(out, 'w')
+ fo.write(decom.read())
+ fo.flush()
+ fo.close()
+ decom.close()
+ elif filename.endswith('.bz') or filename.endswith('.bz2'):
+ if filename.endswith('.bz'):
+ out = filename.replace('.bz','')
+ else:
+ out = filename.replace('.bz2', '')
+ bunzipFile(filename, out)
+
+ #add magical lzma/xz trick here
+
+ return out
+
+
diff --git a/yum/repos.py b/yum/repos.py
index c6ebf8f..cd477ba 100644
--- a/yum/repos.py
+++ b/yum/repos.py
@@ -206,7 +206,7 @@ class RepoStorage:
def setCacheDir(self, cachedir):
"""sets the cachedir value in all repos"""
- self.repos._cachedir = cachedir
+ self._cachedir = cachedir
for repo in self.repos.values():
repo.old_base_cache_dir = repo.basecachedir
repo.basecachedir = cachedir
--
1.6.6
More information about the Yum-devel
mailing list