diff options
Diffstat (limited to 'public')
-rw-r--r-- | public/utils.py | 75 |
1 files changed, 61 insertions, 14 deletions
diff --git a/public/utils.py b/public/utils.py index 8ce2af45..fd29a845 100644 --- a/public/utils.py +++ b/public/utils.py @@ -3,6 +3,51 @@ from operator import attrgetter from main.models import Arch, Package from main.utils import cache_function +class RecentUpdate(object): + def __init__(self, packages): + if len(packages) == 0: + raise Exception + first = packages[0] + self.pkgbase = first.pkgbase + self.repo = first.repo + self.version = '' + + packages = sorted(packages, key=attrgetter('arch', 'pkgname')) + # split the packages into two lists. we need to prefer packages + # matching pkgbase as our primary, and group everything else in other. + self.packages = [pkg for pkg in packages if pkg.pkgname == pkg.pkgbase] + self.others = [pkg for pkg in packages if pkg.pkgname != pkg.pkgbase] + + if self.packages: + version = self.packages[0].full_version + if all(version == pkg.full_version for pkg in self.packages): + self.version = version + elif self.others: + version = self.others[0].full_version + if all(version == pkg.full_version for pkg in self.others): + self.version = version + + def package_links(self): + '''Returns either actual packages or package-standins for virtual + pkgbase packages.''' + if self.packages: + # we have real packages- just yield each in sequence + for package in self.packages: + yield package + else: + # time to fake out the template, this is a tad dirty + arches = set(pkg.arch for pkg in self.others) + for arch in arches: + url = '/packages/%s/%s/%s/' % ( + self.repo.name.lower(), arch.name, self.pkgbase) + package_stub = { + 'pkgname': self.pkgbase, + 'arch': arch, + 'repo': self.repo, + 'get_absolute_url': url + } + yield package_stub + @cache_function(300) def get_recent_updates(number=15): # This is a bit of magic. We are going to show 15 on the front page, but we @@ -10,24 +55,26 @@ def get_recent_updates(number=15): # packages that we can later do some screening and trim out the fat. pkgs = [] # grab a few extra so we can hopefully catch everything we need - fetch = number * 4 + fetch = number * 6 for arch in Arch.objects.all(): pkgs += list(Package.objects.select_related( 'arch', 'repo').filter(arch=arch).order_by('-last_update')[:fetch]) pkgs.sort(key=attrgetter('last_update')) + updates = [] - ctr = 0 - while ctr < number and len(pkgs) > 0: - # not particularly happy with this logic, but it works. - p = pkgs.pop() - is_same = lambda q: p.is_same_version(q) and p.repo == q.repo - samepkgs = filter(is_same, pkgs) - samepkgs.append(p) - samepkgs.sort(key=attrgetter('arch')) - updates.append(samepkgs) - for q in samepkgs: - if p != q: pkgs.remove(q) - ctr += 1 - return updates + while len(pkgs) > 0: + pkg = pkgs.pop() + + in_group = lambda x: pkg.repo == x.repo and pkg.pkgbase == x.pkgbase + samepkgs = [other for other in pkgs if in_group(other)] + samepkgs.append(pkg) + + # now remove all the packages we just pulled out + pkgs = [other for other in pkgs if other not in samepkgs] + + update = RecentUpdate(samepkgs) + updates.append(update) + + return updates[:number] # vim: set ts=4 sw=4 et: |