diff options
author | Dan McGee <dan@archlinux.org> | 2010-08-25 13:45:04 -0500 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2010-08-25 13:45:04 -0500 |
commit | ae5483c230d08c65d91eb7cece106b4f13a56232 (patch) | |
tree | 95fd2c95d29da95a544e1ac110e94e363a91d179 | |
parent | ebfc46026fd726222c32ed1251a4752dee88ca42 (diff) |
Package Differences by Architecture view
Implements FS#20416. Port over the architecture differences view from
archlinux.de and reimplement in Django with our DB schema. Also use a far
simpler SQL query to do the dirty work rather than the triple UNION
operation. This is accomplished by doing a bit more of the fetching work in
code once we know what packages are actually involved.
Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r-- | packages/views.py | 67 | ||||
-rw-r--r-- | templates/packages/differences.html | 37 | ||||
-rw-r--r-- | urls.py | 1 |
3 files changed, 105 insertions, 0 deletions
diff --git a/packages/views.py b/packages/views.py index 277b7900..1ab4749d 100644 --- a/packages/views.py +++ b/packages/views.py @@ -342,4 +342,71 @@ def download(request, name='', repo='', arch=''): url = string.Template('${host}${repo}/os/${arch}/${file}').substitute(details) return HttpResponseRedirect(url) +def arch_differences(request): + from django.db import connection + from operator import itemgetter + # This is a monster. Join packages against itself, looking for packages in + # our non-'any' architectures only, and not having a corresponding package + # entry in the other table (or having one with a different pkgver). We will + # then go and fetch all of these packages from the database and display + # them later using normal ORM models. + # TODO: we have some hardcoded magic here with respect to the arches. + arch_a = Arch.objects.get(name='i686') + arch_b = Arch.objects.get(name='x86_64') + sql = """ +SELECT p.id, q.id + FROM packages p + LEFT JOIN packages q + ON ( + p.pkgname = q.pkgname + AND p.repo_id = q.repo_id + AND p.arch_id != q.arch_id + AND p.id != q.id + ) + WHERE p.arch_id IN (%s, %s) + AND ( + q.id IS NULL + OR + p.pkgver != q.pkgver + OR + p.pkgrel != q.pkgrel + ) +""" + cursor = connection.cursor() + cursor.execute(sql, [arch_a.id, arch_b.id]) + results = cursor.fetchall() + to_fetch = [] + for row in results: + # column A will always have a value, column B might be NULL + to_fetch.append(row[0]) + # fetch all of the necessary packages + pkgs = Package.objects.in_bulk(to_fetch) + # now build a list of tuples containing differences + differences = [] + for row in results: + pkg_a = pkgs.get(row[0]) + pkg_b = pkgs.get(row[1]) + # We want arch_a to always appear first + # pkg_a should never be None + if pkg_a.arch == arch_a: + item = (pkg_a.pkgname, pkg_a.repo, pkg_a, pkg_b) + else: + # pkg_b can be None in this case, so be careful + name = pkg_a.pkgname if pkg_a else pkg_b.pkgname + repo = pkg_a.repo if pkg_a else pkg_b.repo + item = (name, repo, pkg_b, pkg_a) + if item not in differences: + differences.append(item) + + # now sort our list by repository, package name + differences.sort(key=lambda a: (a[1].name, a[0])) + + context = { + 'arch_a': arch_a, + 'arch_b': arch_b, + 'differences': differences, + } + return render_to_response('packages/differences.html', + RequestContext(request, context)) + # vim: set ts=4 sw=4 et: diff --git a/templates/packages/differences.html b/templates/packages/differences.html new file mode 100644 index 00000000..bc749016 --- /dev/null +++ b/templates/packages/differences.html @@ -0,0 +1,37 @@ +{% extends "base.html" %} +{% block title %}Arch Linux - Package Differences by Architecture{% endblock %} +{% block navbarclass %}anb-packages{% endblock %} + +{% block content %} +{% if differences %} +<div class="box"> + <h2>Package Differences by Architecture</h2> + <table class="results"> + <thead> + <tr> + <th>Package Name</th> + <th>Repository</th> + <th>{{ arch_a.name }} Version</th> + <th>{{ arch_b.name }} Version</th> + </tr> + </thead> + <tbody> + {% for name, repo, pkg1, pkg2 in differences %} + <tr class="{% cycle 'odd' 'even' %}"> + <td>{{ name }}</td> + <td>{{ repo.name }}</td> + {% if pkg1 %} + <td><a href="{{ pkg1.get_absolute_url }}" + title="View package details for {{ pkg1.pkgname }}">{{ pkg1.pkgver }}-{{ pkg1.pkgrel }}</a></td> + {% else %}<td>-</td>{% endif %} + {% if pkg2 %} + <td><a href="{{ pkg2.get_absolute_url }}" + title="View package details for {{ pkg2.pkgname }}">{{ pkg2.pkgver }}-{{ pkg2.pkgrel }}</a></td> + {% else %}<td>-</td>{% endif %} + </tr> + {% endfor %} + </tbody> + </table> +</div> +{% endif %} +{% endblock %} @@ -29,6 +29,7 @@ urlpatterns = patterns('', # because other projects link to it (r'^packages/search/$', 'packages.views.search'), (r'^packages/search/(?P<page>\d+)/$', 'packages.views.search'), + (r'^packages/differences/$', 'packages.views.arch_differences'), (r'^packages/$', 'packages.views.search'), (r'^packages/(?P<page>\d+)/$', 'packages.views.search'), |