From ae5483c230d08c65d91eb7cece106b4f13a56232 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 25 Aug 2010 13:45:04 -0500 Subject: 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 --- packages/views.py | 67 +++++++++++++++++++++++++++++++++++++ templates/packages/differences.html | 37 ++++++++++++++++++++ urls.py | 1 + 3 files changed, 105 insertions(+) create mode 100644 templates/packages/differences.html 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 %} +
+

Package Differences by Architecture

+ + + + + + + + + + + {% for name, repo, pkg1, pkg2 in differences %} + + + + {% if pkg1 %} + + {% else %}{% endif %} + {% if pkg2 %} + + {% else %}{% endif %} + + {% endfor %} + +
Package NameRepository{{ arch_a.name }} Version{{ arch_b.name }} Version
{{ name }}{{ repo.name }}{{ pkg1.pkgver }}-{{ pkg1.pkgrel }}-{{ pkg2.pkgver }}-{{ pkg2.pkgrel }}-
+
+{% endif %} +{% endblock %} diff --git a/urls.py b/urls.py index 74c439fc..f2ad6b2a 100644 --- a/urls.py +++ b/urls.py @@ -29,6 +29,7 @@ urlpatterns = patterns('', # because other projects link to it (r'^packages/search/$', 'packages.views.search'), (r'^packages/search/(?P\d+)/$', 'packages.views.search'), + (r'^packages/differences/$', 'packages.views.arch_differences'), (r'^packages/$', 'packages.views.search'), (r'^packages/(?P\d+)/$', 'packages.views.search'), -- cgit v1.1-4-g5e80