From aed00836d5d57c19e8ea2767cafd1340e5e7c00a Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 2 Apr 2012 12:06:48 -0500 Subject: Skip default ordering in sitemaps output The output is not required to be ordered by the specification, so save some effort by skipping any sorting. Signed-off-by: Dan McGee --- sitemaps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sitemaps.py b/sitemaps.py index 8e9ba36f..424168bf 100644 --- a/sitemaps.py +++ b/sitemaps.py @@ -13,7 +13,7 @@ class PackagesSitemap(Sitemap): priority = "0.5" def items(self): - return Package.objects.normal() + return Package.objects.all().order_by() def lastmod(self, obj): return obj.last_update @@ -68,7 +68,7 @@ class NewsSitemap(Sitemap): self.one_week_ago = now - timedelta(days=7) def items(self): - return News.objects.all() + return News.objects.all().order_by() def lastmod(self, obj): return obj.last_modified -- cgit v1.1-4-g5e80 From d9e5cbf546536e4a14e7f3cb591631515112a205 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 2 Apr 2012 12:40:40 -0500 Subject: Make hidden 'name' search field match exactly This is much more useful than the old contains match if you are trying to narrow down your search to a specific package. Signed-off-by: Dan McGee --- packages/views/search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/views/search.py b/packages/views/search.py index 1431893d..a23c6b4a 100644 --- a/packages/views/search.py +++ b/packages/views/search.py @@ -101,7 +101,7 @@ def parse_form(form, packages): if form.cleaned_data['name']: name = form.cleaned_data['name'] - packages = packages.filter(pkgname__icontains=name) + packages = packages.filter(pkgname=name) if form.cleaned_data['desc']: desc = form.cleaned_data['desc'] -- cgit v1.1-4-g5e80 From b1a9818ddee0e3d0cd4d47b6dbf1c1409992227b Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 3 Apr 2012 14:44:02 -0500 Subject: Include category when linking to bug reports Also change the default category to something legit. Signed-off-by: Dan McGee --- main/models.py | 2 +- packages/templatetags/package_extras.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/main/models.py b/main/models.py index 34cbcd17..db926dda 100644 --- a/main/models.py +++ b/main/models.py @@ -115,7 +115,7 @@ class Repo(models.Model): help_text="Is this repo meant for package staging?") bugs_project = models.SmallIntegerField(default=1, help_text="Flyspray project ID for this repository.") - bugs_category = models.SmallIntegerField(default=0, + bugs_category = models.SmallIntegerField(default=2, help_text="Flyspray category ID for this repository.") svn_root = models.CharField(max_length=64, help_text="SVN root (e.g. path) for this repository.") diff --git a/packages/templatetags/package_extras.py b/packages/templatetags/package_extras.py index 5cc826ed..975f59f1 100644 --- a/packages/templatetags/package_extras.py +++ b/packages/templatetags/package_extras.py @@ -110,6 +110,7 @@ def bugs_list(package): url = "https://bugs.archlinux.org/" data = { 'project': package.repo.bugs_project, + 'cat[]': package.repo.bugs_category, 'string': package.pkgname, } return link_encode(url, data) -- cgit v1.1-4-g5e80 From 51526a44ef0ab586c6b2204aa0989a669dcf99a2 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 3 Apr 2012 14:52:42 -0500 Subject: Convert flaghelp page to HTML5 doctype Signed-off-by: Dan McGee --- templates/packages/flaghelp.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/templates/packages/flaghelp.html b/templates/packages/flaghelp.html index 2b5092d2..0fdf47ed 100644 --- a/templates/packages/flaghelp.html +++ b/templates/packages/flaghelp.html @@ -1,6 +1,5 @@ - - + + Flagging Packages -- cgit v1.1-4-g5e80 From ee2a587738f3e571f4e0e61153061ba6853475eb Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 3 Apr 2012 14:55:27 -0500 Subject: Use https:// links for all internal sites We already use HTTPS exclusively for wiki, bugs, forums, etc. and we have it available for our other sites, so link only to the https:// protocol locations when pointing users at other sites. Signed-off-by: Dan McGee --- packages/templatetags/package_extras.py | 2 +- templates/packages/flag.html | 2 +- templates/packages/flaghelp.html | 2 +- templates/public/download.html | 20 ++++++++++---------- templates/public/index.html | 8 ++++---- templates/public/svn.html | 4 ++-- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/templatetags/package_extras.py b/packages/templatetags/package_extras.py index 975f59f1..9daecd96 100644 --- a/packages/templatetags/package_extras.py +++ b/packages/templatetags/package_extras.py @@ -93,7 +93,7 @@ def packager_link(user): def scm_link(package, operation): parts = (package.repo.svn_root, operation, package.pkgbase) linkbase = ( - "http://projects.archlinux.org/svntogit/%s.git/%s/trunk?" + "https://projects.archlinux.org/svntogit/%s.git/%s/trunk?" "h=packages/%s") return linkbase % tuple(urlquote(part) for part in parts) diff --git a/templates/packages/flag.html b/templates/packages/flag.html index 5fc9c91d..d1226295 100644 --- a/templates/packages/flag.html +++ b/templates/packages/flag.html @@ -23,7 +23,7 @@

The message box portion of the flag utility is optional, and meant for short messages only. If you need more than 200 characters for your message, then file a bug report, email the maintainer directly, or send - an email to the arch-general mailing list with your additional text.

diff --git a/templates/packages/flaghelp.html b/templates/packages/flaghelp.html index 0fdf47ed..819a2f01 100644 --- a/templates/packages/flaghelp.html +++ b/templates/packages/flaghelp.html @@ -24,7 +24,7 @@

The message box portion of the flag utility is optional, and meant for short messages only. If you need more than 200 characters for your message, then file a bug report, email the maintainer directly, or send - an email to the arch-general mailing list with your additional text.

diff --git a/templates/public/download.html b/templates/public/download.html index a3ff2a37..67c70be1 100644 --- a/templates/public/download.html +++ b/templates/public/download.html @@ -26,7 +26,7 @@ @@ -35,7 +35,7 @@

Links and Instructions:

    -
  • Readme and Instructions
  • Arch Linux Install Guide
  • @@ -68,13 +68,13 @@ Netinstall Image - Download - Download - Download Downloads and installs packages versions via FTP for absolute freshness. @@ -83,13 +83,13 @@ Core Image - Download - Download - Download Core packages are included on the media. Good for basic off-line installation. @@ -143,9 +143,9 @@

    File integrity checksums for the latest releases can be found below:

    diff --git a/templates/public/index.html b/templates/public/index.html index 04c4795d..de77b47f 100644 --- a/templates/public/index.html +++ b/templates/public/index.html @@ -26,7 +26,7 @@

    Our strong community is diverse and helpful, and we pride ourselves on the range of skillsets and uses for Arch that stem from it. Please check out our forums - and mailing lists to get your feet wet. Also glance through our wiki @@ -126,11 +126,11 @@

    Community

      -
    • Mailing Lists
    • IRC Channels
    • -
    • Planet Arch
    • International Communities
    • @@ -163,7 +163,7 @@

      Development

        -
      • Projects in Git
      • SVN Repositories
      • diff --git a/templates/public/svn.html b/templates/public/svn.html index aedd9a73..0d067098 100644 --- a/templates/public/svn.html +++ b/templates/public/svn.html @@ -9,9 +9,9 @@

        The SVN repositories have been cloned into git repositories and can be viewed via the cgit interface. - All + All packages are available here except for - community + community and multilib which are available in a different repository.

        You can also get individual PKGBUILDs directly from SVN. This can be -- cgit v1.1-4-g5e80 From 84f98e3e0b9ef319f501795099cc32bce1bf6a81 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 5 Apr 2012 09:48:24 -0500 Subject: Show and link key_id if signer was an unknown key Signed-off-by: Dan McGee --- templates/packages/details.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/packages/details.html b/templates/packages/details.html index a066969c..5c08bf11 100644 --- a/templates/packages/details.html +++ b/templates/packages/details.html @@ -151,7 +151,7 @@ {{ pkg.build_date|date:"DATETIME_FORMAT" }} UTC {% if pkg.signature %} Signed By: - {% with pkg.signer as signer %}{% if signer %}{% pgp_key_link pkg.signature.key_id signer.get_full_name %}{% else %}Unknown{% endif %}{% endwith %} + {% with pkg.signer as signer %}{% if signer %}{% pgp_key_link pkg.signature.key_id signer.get_full_name %}{% else %}Unknown ({% pgp_key_link pkg.signature.key_id %}){% endif %}{% endwith %} Signature Date: {{ pkg.signature.datetime|date:"DATETIME_FORMAT" }} UTC -- cgit v1.1-4-g5e80 From 1a2f117037fd8b01ec1e1e3cce5186d7bfac1a78 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Fri, 23 Mar 2012 17:33:55 -0500 Subject: Add a mismatched signatures developer report This finds odd signatures in our repositories, which includes signature times not matching with build dates, different signer and packager, etc. We enhance our user lookup helper class to look up users by PGP key. Signed-off-by: Dan McGee --- devel/utils.py | 17 +++++++++++++++++ devel/views.py | 23 +++++++++++++++++++++-- templates/devel/index.html | 9 ++++++--- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/devel/utils.py b/devel/utils.py index ec035d13..85b4e42f 100644 --- a/devel/utils.py +++ b/devel/utils.py @@ -49,6 +49,7 @@ class UserFinder(object): self.cache = {} self.username_cache = {} self.email_cache = {} + self.pgp_cache = {} @staticmethod def user_email(name, email): @@ -146,9 +147,25 @@ class UserFinder(object): self.email_cache[email] = user return user + def find_by_pgp_key(self, pgp_key): + if not pgp_key: + return None + if pgp_key in self.pgp_cache: + return self.pgp_cache[pgp_key] + + try: + user = User.objects.get( + userprofile__pgp_key__endswith=pgp_key) + except User.DoesNotExist: + user = None + + self.pgp_cache[pgp_key] = user + return user + def clear_cache(self): self.cache = {} self.username_cache = {} self.email_cache = {} + self.pgp_cache = {} # vim: set ts=4 sw=4 et: diff --git a/devel/views.py b/devel/views.py index 3a9be757..3ede54ab 100644 --- a/devel/views.py +++ b/devel/views.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta +from datetime import date, datetime, timedelta import operator import pytz import random @@ -28,7 +28,7 @@ from main.utils import utc_now from packages.models import PackageRelation from packages.utils import get_signoff_groups from todolists.utils import get_annotated_todolists -from .utils import get_annotated_maintainers +from .utils import get_annotated_maintainers, UserFinder @login_required @@ -232,6 +232,25 @@ def report(request, report_name, username=None): # The two separate calls to exclude is required to do the right thing packages = packages.exclude(pkgbase__in=owned).exclude( pkgname__in=required) + elif report_name == 'mismatched-signature': + title = 'Packages with mismatched signatures' + names = [ 'Signature Date', 'Signed By', 'Packager' ] + attrs = [ 'sig_date', 'sig_by', 'packager' ] + cutoff = timedelta(hours=24) + finder = UserFinder() + filtered = [] + packages = packages.filter(pgp_signature__isnull=False) + for package in packages: + sig_date = package.signature.datetime.replace(tzinfo=pytz.utc) + package.sig_date = sig_date.date() + key_id = package.signature.key_id + signer = finder.find_by_pgp_key(key_id) + package.sig_by = signer or key_id + if signer is None or signer.id != package.packager_id: + filtered.append(package) + elif sig_date > package.build_date + cutoff: + filtered.append(package) + packages = filtered else: raise Http404 diff --git a/templates/devel/index.html b/templates/devel/index.html index 63d18193..7c26aab7 100644 --- a/templates/devel/index.html +++ b/templates/devel/index.html @@ -147,9 +147,6 @@

        Developer Reports

          -
        • Big: - All packages with compressed size > 50 MiB - (yours only)
        • Old: Packages last built more than two years ago (yours only)
        • @@ -162,6 +159,12 @@
        • Uncompressed Info Pages: Self-explanatory (yours only)
        • +
        • Mismatched Signatures: + Packages where 1) signing key is unknown, 2) signer != packager, or 3) signature timestamp more than 24 hours after build timestamp + (yours only)
        • +
        • Big: + All packages with compressed size > 50 MiB + (yours only)
        • Bad Compression: Packages with a compression ratio of less than 10% (yours only)
        • -- cgit v1.1-4-g5e80 From b5ab5b1e218219b09857b06f88e522bccb4b5600 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 7 Apr 2012 14:39:01 -0500 Subject: Choose an up-to-date mirror for download URLs Given that we collect a lot of mirror status data, we can utilize it to ensure the download link on the website actually works and newly-added packages have actually been mirrored out. Add a method that attempts to use the mirror status data to determine a mirror we should redirect our download requests to. This can change on a regular basis, and falls back to the old method if no mirror status data is available. Signed-off-by: Dan McGee --- mirrors/utils.py | 34 ++++++++++++++++++++++++++++++++++ packages/views/__init__.py | 13 ++++--------- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/mirrors/utils.py b/mirrors/utils.py index 0f8fef84..619d5f5c 100644 --- a/mirrors/utils.py +++ b/mirrors/utils.py @@ -27,6 +27,7 @@ def annotate_url(url, delays): url.delay = None url.score = None + @cache_function(123) def get_mirror_statuses(cutoff=default_cutoff): cutoff_time = utc_now() - cutoff @@ -81,6 +82,7 @@ def get_mirror_statuses(cutoff=default_cutoff): 'urls': urls, } + @cache_function(117) def get_mirror_errors(cutoff=default_cutoff): cutoff_time = utc_now() - cutoff @@ -96,4 +98,36 @@ def get_mirror_errors(cutoff=default_cutoff): err['country'] = err['url__country'] or err['url__mirror__country'] return errors + +@cache_function(295) +def get_mirror_url_for_download(cutoff=default_cutoff): + '''Find a good mirror URL to use for package downloads. If we have mirror + status data available, it is used to determine a good choice by looking at + the last batch of status rows.''' + cutoff_time = utc_now() - cutoff + status_data = MirrorLog.objects.filter( + check_time__gte=cutoff_time).aggregate( + Max('check_time'), Max('last_sync')) + if status_data: + min_check_time = status_data['check_time__max'] - timedelta(minutes=5) + min_sync_time = status_data['last_sync__max'] - timedelta(minutes=30) + best_logs = MirrorLog.objects.filter(is_success=True, + check_time__gte=min_check_time, last_sync__gte=min_sync_time, + url__mirror__public=True, url__mirror__active=True, + url__protocol__protocol__iexact='HTTP').order_by( + 'duration')[:1] + if best_logs: + return MirrorUrl.objects.get(id=best_logs[0].url_id) + + mirror_urls = MirrorUrl.objects.filter( + mirror__public=True, mirror__active=True, + protocol__protocol__iexact='HTTP') + # look first for an 'Any' URL, then fall back to any HTTP URL + filtered_urls = mirror_urls.filter(mirror__country='Any')[:1] + if not filtered_urls: + filtered_urls = mirror_urls[:1] + if not filtered_urls: + return None + return filtered_urls[0] + # vim: set ts=4 sw=4 et: diff --git a/packages/views/__init__.py b/packages/views/__init__.py index 2798fff1..abc86d78 100644 --- a/packages/views/__init__.py +++ b/packages/views/__init__.py @@ -14,6 +14,7 @@ from django.views.generic.simple import direct_to_template from main.models import Package, PackageFile, PackageDepend, Arch, Repo from mirrors.models import MirrorUrl +from mirrors.utils import get_mirror_url_for_download from ..models import (PackageRelation, PackageGroup, License, Conflict, Provision, Replacement) from ..utils import (get_group_info, get_differences_info, @@ -225,21 +226,15 @@ def files_json(request, name, repo, arch): def download(request, name, repo, arch): pkg = get_object_or_404(Package, pkgname=name, repo__name__iexact=repo, arch__name=arch) - mirror_urls = MirrorUrl.objects.filter( - mirror__public=True, mirror__active=True, - protocol__protocol__iexact='HTTP') - # look first for an 'Any' URL, then fall back to any HTTP URL - filtered_urls = mirror_urls.filter(mirror__country='Any')[:1] - if not filtered_urls: - filtered_urls = mirror_urls[:1] - if not filtered_urls: + url = get_mirror_url_for_download() + if not url: raise Http404 arch = pkg.arch.name if pkg.arch.agnostic: # grab the first non-any arch to fake the download path arch = Arch.objects.exclude(agnostic=True)[0].name values = { - 'host': filtered_urls[0].url, + 'host': url.url, 'arch': arch, 'repo': pkg.repo.name.lower(), 'file': pkg.filename, -- cgit v1.1-4-g5e80 From 068bc8db6bbfd9e1ed078d72169f34da97914c82 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 7 Apr 2012 14:44:06 -0500 Subject: Move PackageJSONEncoder into package.utils module This will allow it to be used elsewhere, and doesn't really belong in views anyway. Signed-off-by: Dan McGee --- packages/utils.py | 37 ++++++++++++++++++++++++++++++++++++- packages/views/__init__.py | 39 +++------------------------------------ 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/packages/utils.py b/packages/utils.py index 2a43a08b..a3c13b17 100644 --- a/packages/utils.py +++ b/packages/utils.py @@ -2,13 +2,15 @@ from collections import defaultdict from itertools import chain from operator import itemgetter +from django.core.serializers.json import DjangoJSONEncoder from django.db import connection from django.db.models import Count, Max, F from django.contrib.auth.models import User -from main.models import Package, Arch, Repo +from main.models import Package, PackageDepend, PackageFile, Arch, Repo from main.utils import cache_function, groupby_preserve_order, PackageStandin from .models import (PackageGroup, PackageRelation, + License, Conflict, Provision, Replacement, SignoffSpecification, Signoff, DEFAULT_SIGNOFF_SPEC) @cache_function(127) @@ -422,4 +424,37 @@ def get_signoff_groups(repos=None, user=None): return signoff_groups + +class PackageJSONEncoder(DjangoJSONEncoder): + pkg_attributes = [ 'pkgname', 'pkgbase', 'repo', 'arch', 'pkgver', + 'pkgrel', 'epoch', 'pkgdesc', 'url', 'filename', 'compressed_size', + 'installed_size', 'build_date', 'last_update', 'flag_date', + 'maintainers', 'packager' ] + pkg_list_attributes = [ 'groups', 'licenses', 'conflicts', + 'provides', 'replaces', 'depends' ] + + def default(self, obj): + if hasattr(obj, '__iter__'): + # mainly for queryset serialization + return list(obj) + if isinstance(obj, Package): + data = dict((attr, getattr(obj, attr)) + for attr in self.pkg_attributes) + for attr in self.pkg_list_attributes: + data[attr] = getattr(obj, attr).all() + return data + if isinstance(obj, PackageFile): + filename = obj.filename or '' + return obj.directory + filename + if isinstance(obj, (Repo, Arch)): + return obj.name.lower() + if isinstance(obj, (PackageGroup, License)): + return obj.name + if isinstance(obj, (Conflict, Provision, Replacement, PackageDepend)): + return unicode(obj) + elif isinstance(obj, User): + return obj.username + return super(PackageJSONEncoder, self).default(obj) + + # vim: set ts=4 sw=4 et: diff --git a/packages/views/__init__.py b/packages/views/__init__.py index abc86d78..2ed266e9 100644 --- a/packages/views/__init__.py +++ b/packages/views/__init__.py @@ -4,7 +4,6 @@ from urllib import urlencode from django.contrib import messages from django.contrib.auth.decorators import permission_required from django.contrib.auth.models import User -from django.core.serializers.json import DjangoJSONEncoder from django.http import HttpResponse, Http404 from django.shortcuts import get_object_or_404, redirect from django.utils import simplejson @@ -12,13 +11,12 @@ from django.views.decorators.http import require_POST from django.views.decorators.vary import vary_on_headers from django.views.generic.simple import direct_to_template -from main.models import Package, PackageFile, PackageDepend, Arch, Repo +from main.models import Package, PackageFile, Arch, Repo from mirrors.models import MirrorUrl from mirrors.utils import get_mirror_url_for_download -from ..models import (PackageRelation, PackageGroup, License, - Conflict, Provision, Replacement) +from ..models import PackageRelation from ..utils import (get_group_info, get_differences_info, - multilib_differences, get_wrong_permissions) + multilib_differences, get_wrong_permissions, PackageJSONEncoder) # make other views available from this same package from .flag import flaghelp, flag, flag_confirmed, unflag, unflag_all @@ -26,37 +24,6 @@ from .search import search from .signoff import signoffs, signoff_package, signoff_options, signoffs_json -class PackageJSONEncoder(DjangoJSONEncoder): - pkg_attributes = [ 'pkgname', 'pkgbase', 'repo', 'arch', 'pkgver', - 'pkgrel', 'epoch', 'pkgdesc', 'url', 'filename', 'compressed_size', - 'installed_size', 'build_date', 'last_update', 'flag_date', - 'maintainers', 'packager' ] - pkg_list_attributes = [ 'groups', 'licenses', 'conflicts', - 'provides', 'replaces', 'depends' ] - - def default(self, obj): - if hasattr(obj, '__iter__'): - # mainly for queryset serialization - return list(obj) - if isinstance(obj, Package): - data = dict((attr, getattr(obj, attr)) - for attr in self.pkg_attributes) - for attr in self.pkg_list_attributes: - data[attr] = getattr(obj, attr).all() - return data - if isinstance(obj, PackageFile): - filename = obj.filename or '' - return obj.directory + filename - if isinstance(obj, (Repo, Arch)): - return obj.name.lower() - if isinstance(obj, (PackageGroup, License)): - return obj.name - if isinstance(obj, (Conflict, Provision, Replacement, PackageDepend)): - return unicode(obj) - elif isinstance(obj, User): - return obj.username - return super(PackageJSONEncoder, self).default(obj) - def opensearch(request): if request.is_secure(): domain = "https://%s" % request.META['HTTP_HOST'] -- cgit v1.1-4-g5e80 From ec7130f6ac194ce7ad53d06e3169030b16da6fed Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 7 Apr 2012 14:50:26 -0500 Subject: Allow sorting of lower table on master keys page Add some styling for sortable pretty2 tables to the CSS, and convert the header row into a single row since that is all tablesorter seems to support correctly when assigning styles. Signed-off-by: Dan McGee --- sitestatic/archweb.css | 17 +++++++++++++++++ templates/public/keys.html | 23 ++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/sitestatic/archweb.css b/sitestatic/archweb.css index ac0dff52..a7fe6cac 100644 --- a/sitestatic/archweb.css +++ b/sitestatic/archweb.css @@ -258,6 +258,23 @@ table.pretty2 { border: 1px solid #bbb; } + /* additional styles for JS sorting */ + table.pretty2 th.header { + padding-right: 20px; + background-image: url(nosort.gif); + background-repeat: no-repeat; + background-position: center right; + cursor: pointer; + } + + table.pretty2 th.headerSortDown { + background-image: url(desc.gif); + } + + table.pretty2 th.headerSortUp { + background-image: url(asc.gif); + } + table.pretty2 td { padding: 0.35em; border: 1px dotted #bbb; diff --git a/templates/public/keys.html b/templates/public/keys.html index a7c91c43..05524c48 100644 --- a/templates/public/keys.html +++ b/templates/public/keys.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load static from staticfiles %} {% load pgp %} {% block title %}Arch Linux - Master Signing Keys{% endblock %} @@ -66,17 +67,11 @@ - + {% for key in keys %} - - {% endfor %} - - - - - {% for key in keys %} - + {% endfor %} @@ -94,4 +89,14 @@
          Developer PGP Key{{ key.owner.get_full_name }}
          {% pgp_key_link key.pgp_key %}{{ key.owner.get_full_name }}
          + {% pgp_key_link key.pgp_key %}
          +{% load cdn %}{% jquery %} + + + {% endblock %} -- cgit v1.1-4-g5e80 From 9684e7c095585059033ac29339b058931a6547e3 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 7 Apr 2012 14:51:25 -0500 Subject: Prevent selection of many useless fields when getting todolists This is a bit of a hack, but makes the resulting resultset returned from the database a lot smaller and kills off all the columns we don't care about and would never look at. Signed-off-by: Dan McGee --- todolists/utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/todolists/utils.py b/todolists/utils.py index 894f3f1d..24101e86 100644 --- a/todolists/utils.py +++ b/todolists/utils.py @@ -2,9 +2,13 @@ from django.db.models import Count from main.models import Todolist + def get_annotated_todolists(): qs = Todolist.objects.all() - lists = qs.select_related('creator').annotate( + lists = qs.select_related('creator').defer( + 'creator__email', 'creator__password', 'creator__is_staff', + 'creator__is_active', 'creator__is_superuser', + 'creator__last_login', 'creator__date_joined').annotate( pkg_count=Count('todolistpkg')).order_by('-date_added') incomplete = qs.filter(todolistpkg__complete=False).annotate( Count('todolistpkg')).values_list('id', 'todolistpkg__count') -- cgit v1.1-4-g5e80 From 5d9f87c02bd8ad73fdb27600e0afe71284e3082f Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 7 Apr 2012 14:52:39 -0500 Subject: Add JSON search view This still might change and should not be viewed as a public API yet. This has been a longstanding request in FS#13026. Signed-off-by: Dan McGee --- packages/urls.py | 1 + packages/views/__init__.py | 2 +- packages/views/search.py | 26 ++++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/urls.py b/packages/urls.py index 7e12a239..6eddc5fe 100644 --- a/packages/urls.py +++ b/packages/urls.py @@ -22,6 +22,7 @@ urlpatterns = patterns('packages.views', (r'^update/$', 'update'), (r'^$', 'search', {}, 'packages-search'), + (r'^search/json/$', 'search_json'), (r'^(?P\d+)/$', 'search'), (r'^differences/$', 'arch_differences', {}, 'packages-differences'), diff --git a/packages/views/__init__.py b/packages/views/__init__.py index 2ed266e9..6a9c5275 100644 --- a/packages/views/__init__.py +++ b/packages/views/__init__.py @@ -20,7 +20,7 @@ from ..utils import (get_group_info, get_differences_info, # make other views available from this same package from .flag import flaghelp, flag, flag_confirmed, unflag, unflag_all -from .search import search +from .search import search, search_json from .signoff import signoffs, signoff_package, signoff_options, signoffs_json diff --git a/packages/views/search.py b/packages/views/search.py index a23c6b4a..a09de0a7 100644 --- a/packages/views/search.py +++ b/packages/views/search.py @@ -4,11 +4,14 @@ from django import forms from django.contrib.admin.widgets import AdminDateWidget from django.contrib.auth.models import User from django.db.models import Q +from django.http import HttpResponse from django.views.generic import list_detail +from django.utils import simplejson from main.models import Package, Arch, Repo from main.utils import make_choice from ..models import PackageRelation +from ..utils import PackageJSONEncoder def coerce_limit_value(value): @@ -157,4 +160,27 @@ def search(request, page=None): template_object_name="package", extra_context=page_dict) + +def search_json(request): + limit = 250 + + container = { + 'version': 2, + 'limit': limit, + 'valid': False, + 'results': [], + } + + if request.GET: + form = PackageSearchForm(data=request.GET) + if form.is_valid(): + packages = Package.objects.normal() + packages = parse_form(form, packages)[:limit] + container['results'] = packages + container['valid'] = True + + to_json = simplejson.dumps(container, ensure_ascii=False, + cls=PackageJSONEncoder) + return HttpResponse(to_json, mimetype='application/json') + # vim: set ts=4 sw=4 et: -- cgit v1.1-4-g5e80