From 21c48f9fbcdc6c42d664a09bda85285cbc7d72ec Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 27 Nov 2010 14:43:01 -0600 Subject: Add less-than methods for Repo and Arch These are the methods guaranteed to be used by the python sort functions; define them so we can simplify sorting code elsewhere as needed. Signed-off-by: Dan McGee --- main/models.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'main') diff --git a/main/models.py b/main/models.py index 6fdb862f..51cf89a8 100644 --- a/main/models.py +++ b/main/models.py @@ -67,6 +67,9 @@ class Arch(models.Model): def __unicode__(self): return self.name + def __lt__(self, other): + return self.name < other.name + class Meta: db_table = 'arches' ordering = ['name'] @@ -85,6 +88,9 @@ class Repo(models.Model): def __unicode__(self): return self.name + def __lt__(self, other): + return self.name < other.name + class Meta: db_table = 'repos' ordering = ['name'] -- cgit v1.2.3-2-g168b From 681dba9eef7991c5113d35562b3ace55bb782ad4 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 7 Dec 2010 13:31:59 -0600 Subject: Move some common package code to a function We do this determination of 'applicable arches' a few times, so move it to a method on the package object and also clean things up so items aren't duplicated in the list. Signed-off-by: Dan McGee --- main/models.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'main') diff --git a/main/models.py b/main/models.py index 51cf89a8..af4466ff 100644 --- a/main/models.py +++ b/main/models.py @@ -156,16 +156,21 @@ class Package(models.Model): def approved_for_signoff(self): return len(self.signoffs) >= 2 + @cache_function(300) + def applicable_arches(self): + '''The list of (this arch) + (available agnostic arches).''' + arches = set(Arch.objects.filter(agnostic=True)) + arches.add(self.arch) + return list(arches) + @cache_function(300) def get_requiredby(self): """ Returns a list of package objects. """ - arches = list(Arch.objects.filter(agnostic=True)) - arches.append(self.arch) requiredby = Package.objects.select_related('arch', 'repo').filter( packagedepend__depname=self.pkgname, - arch__in=arches).distinct() + arch__in=self.applicable_arches()).distinct() return requiredby.order_by('pkgname') @cache_function(300) @@ -176,15 +181,13 @@ class Package(models.Model): else pkg will be None if it is a 'virtual' dependency. """ deps = [] - arches = list(Arch.objects.filter(agnostic=True)) - arches.append(self.arch) # TODO: we can use list comprehension and an 'in' query to make this more effective for dep in self.packagedepend_set.order_by('depname'): pkgs = Package.objects.select_related('arch', 'repo').filter( pkgname=dep.depname) if not self.arch.agnostic: # make sure we match architectures if possible - pkgs = pkgs.filter(arch__in=arches) + pkgs = pkgs.filter(arch__in=self.applicable_arches()) if len(pkgs) == 0: # couldn't find a package in the DB # it should be a virtual depend (or a removed package) @@ -231,7 +234,7 @@ class Package(models.Model): repo.testing flag. For any non-split packages, the return value will be an empty list. """ - return Package.objects.filter(arch=self.arch, + return Package.objects.filter(arch__in=self.applicable_arches, repo__testing=self.repo.testing, pkgbase=self.pkgbase).exclude(id=self.id) def get_svn_link(self, svnpath): -- cgit v1.2.3-2-g168b From e8feaa3e01fdb326e82139ff80fce34f7e088438 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 7 Dec 2010 13:52:40 -0600 Subject: Save DB query when filtering dependencies for testing Signed-off-by: Dan McGee --- main/models.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'main') diff --git a/main/models.py b/main/models.py index af4466ff..ec2416f7 100644 --- a/main/models.py +++ b/main/models.py @@ -198,10 +198,8 @@ class Package(models.Model): # more than one package, see if we can't shrink it down # grab the first though in case we fail pkg = pkgs[0] - if self.repo.testing: - pkgs = pkgs.filter(repo__testing=True) - else: - pkgs = pkgs.filter(repo__testing=False) + # prevents yet more DB queries, these lists should be short + pkgs = [p for p in pkgs if p.repo.testing == self.repo.testing] if len(pkgs) > 0: pkg = pkgs[0] deps.append({'dep': dep, 'pkg': pkg}) -- cgit v1.2.3-2-g168b From fc3ab08cb5663f9b3189b7e04bfd73e7ba2c3e92 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 7 Dec 2010 14:12:03 -0600 Subject: Slim down required by listings If we have testing/non-testing packages in this list, and we are looking at a package that is in both testing and non-testing, we can show only the packages that correspond with the relevant repo. I'm not sure any explanation will make this easier to understand, but the end result is we don't show a bunch of duplicates where we used to. Signed-off-by: Dan McGee --- main/models.py | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'main') diff --git a/main/models.py b/main/models.py index ec2416f7..b5c395a4 100644 --- a/main/models.py +++ b/main/models.py @@ -5,6 +5,9 @@ from django.contrib.sites.models import Site from main.utils import cache_function from packages.models import PackageRelation +from itertools import groupby +from operator import attrgetter + class UserProfile(models.Model): id = models.AutoField(primary_key=True) # not technically needed notify = models.BooleanField( @@ -166,19 +169,43 @@ class Package(models.Model): @cache_function(300) def get_requiredby(self): """ - Returns a list of package objects. + Returns a list of package objects. An attempt will be made to keep this + list slim by including the corresponding package in the same testing + category as this package if that check makes sense. """ requiredby = Package.objects.select_related('arch', 'repo').filter( packagedepend__depname=self.pkgname, - arch__in=self.applicable_arches()).distinct() - return requiredby.order_by('pkgname') + arch__in=self.applicable_arches() + ).distinct().order_by('pkgname') + + # find another package by this name in the opposite testing setup + if not Package.objects.filter(pkgname=self.pkgname, + arch=self.arch).exclude(id=self.id, + repo__testing=self.repo.testing).exists(): + # there isn't one? short circuit, all required by entries are fine + return requiredby + + trimmed = [] + # for each unique package name, try to screen our package list down to + # those packages in the same testing category (yes or no) iff there is + # a package in the same testing category. + for name, pkgs in groupby(requiredby, attrgetter('pkgname')): + pkgs = list(pkgs) + pkg = pkgs[0] + if len(pkgs) > 1: + pkgs = [p for p in pkgs if p.repo.testing == self.repo.testing] + if len(pkgs) > 0: + pkg = pkgs[0] + trimmed.append(pkg) + return trimmed @cache_function(300) def get_depends(self): """ - Returns a list of dicts. Each dict contains ('pkg' and 'dep'). - If it represents a found package both vars will be available; - else pkg will be None if it is a 'virtual' dependency. + Returns a list of dicts. Each dict contains ('pkg' and 'dep'). If it + represents a found package both vars will be available; else pkg will + be None if it is a 'virtual' dependency. Packages will match the + testing status of this package if possible. """ deps = [] # TODO: we can use list comprehension and an 'in' query to make this more effective -- cgit v1.2.3-2-g168b From 97e8489ecbfc85c3759afdbe59605f3c0ffb4ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=A4chler?= Date: Tue, 14 Dec 2010 21:06:30 +0100 Subject: Get rid of all references to repos.archlinux.org The packages/community repositories can now be viewed via cgit. Point links to cgit instead of websvn, as websvn is buggy and nobody wants to maintain it. This allows us to get rid of websvn entirely. Signed-off-by: Dan McGee --- main/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'main') diff --git a/main/models.py b/main/models.py index b5c395a4..8858b17b 100644 --- a/main/models.py +++ b/main/models.py @@ -263,7 +263,7 @@ class Package(models.Model): repo__testing=self.repo.testing, pkgbase=self.pkgbase).exclude(id=self.id) def get_svn_link(self, svnpath): - linkbase = "http://repos.archlinux.org/wsvn/%s/%s/%s/" + linkbase = "http://projects.archlinux.org/svntogit/%s.git/tree/%s/%s/" return linkbase % (self.repo.svn_root, self.pkgbase, svnpath) def get_arch_svn_link(self): -- cgit v1.2.3-2-g168b