summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-08-09 23:33:27 -0500
committerDan McGee <dan@archlinux.org>2011-08-09 23:33:27 -0500
commit02c0dbc482fc6037c19e713f4645d627eb004e9c (patch)
tree93b3379ddd3e751d62f5f7a9a289b8f468c688ab
parent156b91eb5935df4afdb8f0f0311d36537808c2f5 (diff)
Add some methods to PackageDepend object
This will allow for some future "find the best provider link" stuff as well as refactoring of the get_depends() method on Package. Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--main/models.py58
1 files changed, 58 insertions, 0 deletions
diff --git a/main/models.py b/main/models.py
index 70372823..4897cb65 100644
--- a/main/models.py
+++ b/main/models.py
@@ -386,6 +386,64 @@ class PackageDepend(models.Model):
optional = models.BooleanField(default=False)
description = models.TextField(null=True, blank=True)
+ def get_best_satisfier(self, arches=None, testing=None, staging=None):
+ '''Find a satisfier for this dependency that best matches the given
+ criteria. It will not search provisions, but will find packages named
+ and matching repo characteristics if possible.'''
+ pkgs = Package.objects.normal().filter(pkgname=self.depname)
+ if arches is not None:
+ # make sure we match architectures if possible
+ pkgs = pkgs.filter(arch__in=arches)
+ if len(pkgs) == 0:
+ # couldn't find a package in the DB
+ # it should be a virtual depend (or a removed package)
+ return None
+ if len(pkgs) == 1:
+ return pkgs[0]
+ # more than one package, see if we can't shrink it down
+ # grab the first though in case we fail
+ pkg = pkgs[0]
+ # prevents yet more DB queries, these lists should be short;
+ # after each grab the best available in case we remove all entries
+ if staging is not None:
+ pkgs = [p for p in pkgs if p.repo.staging == staging]
+ if len(pkgs) > 0:
+ pkg = pkgs[0]
+
+ if testing is not None:
+ pkgs = [p for p in pkgs if p.repo.testing == testing]
+ if len(pkgs) > 0:
+ pkg = pkgs[0]
+
+ return pkg
+
+ def get_providers(self, arches=None, testing=None, staging=None):
+ '''Return providers of this dep. Does *not* include exact matches as it
+ checks the Provision names only, use get_best_satisfier() instead.'''
+ pkgs = Package.objects.normal().filter(
+ provides__name=self.depname).distinct()
+ if arches is not None:
+ pkgs = pkgs.filter(arch__in=arches)
+
+ # Logic here is to filter out packages that are in multiple repos if
+ # they are not requested. For example, if testing is False, only show a
+ # testing package if it doesn't exist in a non-testing repo.
+ if staging is not None:
+ filtered = {}
+ for p in pkgs:
+ if p.pkgname not in filtered or p.repo.staging == staging:
+ filtered[p.pkgname] = p
+ pkgs = filtered.values()
+
+ if testing is not None:
+ filtered = {}
+ for p in pkgs:
+ if p.pkgname not in filtered or p.repo.testing == testing:
+ filtered[p.pkgname] = p
+ pkgs = filtered.values()
+
+ return pkgs
+
def __unicode__(self):
return "%s%s" % (self.depname, self.depvcmp)