From 76c37ce3acc7a4af0271c7535d4a33042f7749b5 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 24 Jul 2012 09:35:55 -0500 Subject: Replace deprecated direct_to_template() with render() shortcut Now that Django actually provides a concise way to use a RequestContext object without instantiating it, we can use that rather than the old function-based generic view that worked well to do the same. Additionally, these function-based generic views will be gone in Django 1.5, so might as well make the move now. Signed-off-by: Dan McGee --- public/views.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'public') diff --git a/public/views.py b/public/views.py index 3ea8f841..3f68545c 100644 --- a/public/views.py +++ b/public/views.py @@ -5,8 +5,8 @@ from django.conf import settings from django.contrib.auth.models import User from django.db.models import Count, Q from django.http import Http404 +from django.shortcuts import render from django.views.decorators.cache import cache_control -from django.views.generic.simple import direct_to_template from devel.models import MasterKey, PGPSignature from main.models import Arch, Repo, Donor @@ -21,7 +21,7 @@ def index(request): 'news_updates': News.objects.order_by('-postdate', '-id')[:15], 'pkg_updates': pkgs, } - return direct_to_template(request, 'public/index.html', context) + return render(request, 'public/index.html', context) USER_LISTS = { 'devs': { @@ -55,14 +55,14 @@ def userlist(request, user_type='devs'): users = users.distinct() context = USER_LISTS[user_type].copy() context['users'] = users - return direct_to_template(request, 'public/userlist.html', context) + return render(request, 'public/userlist.html', context) @cache_control(max_age=300) def donate(request): context = { 'donors': Donor.objects.filter(visible=True).order_by('name'), } - return direct_to_template(request, 'public/donate.html', context) + return render(request, 'public/donate.html', context) @cache_control(max_age=300) def download(request): @@ -76,7 +76,7 @@ def download(request): 'releng_pxeboot_url': settings.PXEBOOT_URL, 'mirror_urls': mirror_urls, } - return direct_to_template(request, 'public/download.html', context) + return render(request, 'public/download.html', context) @cache_control(max_age=300) def feeds(request): @@ -84,7 +84,7 @@ def feeds(request): 'arches': Arch.objects.all(), 'repos': Repo.objects.all(), } - return direct_to_template(request, 'public/feeds.html', context) + return render(request, 'public/feeds.html', context) @cache_control(max_age=300) def keys(request): @@ -113,6 +113,6 @@ def keys(request): 'active_users': users, 'signatures': signatures, } - return direct_to_template(request, 'public/keys.html', context) + return render(request, 'public/keys.html', context) # vim: set ts=4 sw=4 et: -- cgit v1.2.3 From 0cc369e985dd6376f0367e4b57e980ce14231796 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 31 Jul 2012 00:09:28 -0500 Subject: Update several bits and pieces for staging packages This will prevent [staging] packages from cluttering normal user's view on the website, but allow us to still import everything from this repository for developer use. Signed-off-by: Dan McGee --- public/utils.py | 12 +++++++++--- public/views.py | 5 ++++- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'public') diff --git a/public/utils.py b/public/utils.py index a40c9b53..bf74881a 100644 --- a/public/utils.py +++ b/public/utils.py @@ -1,6 +1,6 @@ from operator import attrgetter -from main.models import Arch, Package +from main.models import Arch, Repo, Package from main.utils import cache_function, groupby_preserve_order, PackageStandin class RecentUpdate(object): @@ -50,7 +50,13 @@ class RecentUpdate(object): yield PackageStandin(package) @cache_function(62) -def get_recent_updates(number=15): +def get_recent_updates(number=15, testing=True, staging=False): + repos = Repo.objects.all() + if not testing: + repos = repos.exclude(testing=True) + if not staging: + repos = repos.exclude(staging=True) + # This is a bit of magic. We are going to show 15 on the front page, but we # want to try and eliminate cross-architecture wasted space. Pull enough # packages that we can later do some screening and trim out the fat. @@ -59,7 +65,7 @@ def get_recent_updates(number=15): fetch = number * 6 for arch in Arch.objects.all(): pkgs += list(Package.objects.normal().filter( - arch=arch).order_by('-last_update')[:fetch]) + arch=arch, repo__in=repos).order_by('-last_update')[:fetch]) pkgs.sort(key=attrgetter('last_update'), reverse=True) same_pkgbase_key = lambda x: (x.repo.name, x.pkgbase) diff --git a/public/views.py b/public/views.py index 3f68545c..c8854b72 100644 --- a/public/views.py +++ b/public/views.py @@ -16,7 +16,10 @@ from .utils import get_recent_updates @cache_control(max_age=300) def index(request): - pkgs = get_recent_updates() + if request.user.is_authenticated(): + pkgs = get_recent_updates(testing=True, staging=True) + else: + pkgs = get_recent_updates() context = { 'news_updates': News.objects.order_by('-postdate', '-id')[:15], 'pkg_updates': pkgs, -- cgit v1.2.3 From 3f0c024754047d92e8ce4aa4ecf93a06865f8448 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 31 Jul 2012 18:37:30 -0500 Subject: PGP key handling updates * Import signatures for all known keys, not just active developers * Ensure we are only showing and accounting for active developers on the master keys page * Add a new table showing signatures between developers Signed-off-by: Dan McGee --- public/views.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'public') diff --git a/public/views.py b/public/views.py index c8854b72..312cb3b2 100644 --- a/public/views.py +++ b/public/views.py @@ -91,30 +91,38 @@ def feeds(request): @cache_control(max_age=300) def keys(request): + users = User.objects.filter(is_active=True).select_related( + 'userprofile__pgp_key').order_by('first_name', 'last_name') + user_key_ids = frozenset(user.userprofile.pgp_key[-16:] for user in users + if user.userprofile.pgp_key) + not_expired = Q(expires__gt=datetime.utcnow) | Q(expires__isnull=True) master_keys = MasterKey.objects.select_related('owner', 'revoker', 'owner__userprofile', 'revoker__userprofile').filter( revoked__isnull=True) + master_key_ids = frozenset(key.pgp_key[-16:] for key in master_keys) - sig_counts = PGPSignature.objects.filter( - not_expired, valid=True).values_list('signer').annotate( + sig_counts = PGPSignature.objects.filter(not_expired, valid=True, + signee__in=user_key_ids).values_list('signer').annotate( Count('signer')) sig_counts = dict((key_id[-16:], ct) for key_id, ct in sig_counts) for key in master_keys: key.signature_count = sig_counts.get(key.pgp_key[-16:], 0) - users = User.objects.filter(is_active=True).select_related( - 'userprofile__pgp_key').order_by('first_name', 'last_name') - # frozenset because we are going to do lots of __contains__ lookups signatures = frozenset(PGPSignature.objects.filter( not_expired, valid=True).values_list('signer', 'signee')) + restrict = Q(signer__in=user_key_ids) & Q(signee__in=user_key_ids) + cross_signatures = PGPSignature.objects.filter(restrict, + not_expired, valid=True).order_by('created') + context = { 'keys': master_keys, 'active_users': users, 'signatures': signatures, + 'cross_signatures': cross_signatures, } return render(request, 'public/keys.html', context) -- cgit v1.2.3 From 3eed426027ed6bc87b58f82d48da06bea55b265f Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 25 Sep 2012 00:30:05 -0500 Subject: Add structured data to developer listing pages Signed-off-by: Dan McGee --- public/views.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'public') diff --git a/public/views.py b/public/views.py index 312cb3b2..35315e0e 100644 --- a/public/views.py +++ b/public/views.py @@ -29,14 +29,17 @@ def index(request): USER_LISTS = { 'devs': { 'user_type': 'Developers', + 'user_title': 'Developer', 'description': "This is a list of the current Arch Linux Developers. They maintain the [core] and [extra] package repositories in addition to doing any other developer duties.", }, 'tus': { 'user_type': 'Trusted Users', + 'user_title': 'Trusted User', 'description': "Here are all your friendly Arch Linux Trusted Users who are in charge of the [community] repository.", }, 'fellows': { 'user_type': 'Fellows', + 'user_title': 'Fellow', 'description': "Below you can find a list of ex-developers (aka project fellows). These folks helped make Arch what it is today. Thanks!", }, } -- cgit v1.2.3 From 67fef06fe8d07e8b832e447a6b2064fb051a5ef9 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 25 Sep 2012 00:49:54 -0500 Subject: Only show staging feeds to logged-in users This doesn't prevent unauthenticated users from accessing the feeds, but it should reduce clutter and confusion on the feeds index page for users unlikely to need these feeds. Signed-off-by: Dan McGee --- public/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'public') diff --git a/public/views.py b/public/views.py index 35315e0e..42f2f345 100644 --- a/public/views.py +++ b/public/views.py @@ -86,9 +86,12 @@ def download(request): @cache_control(max_age=300) def feeds(request): + repos = Repo.objects.all() + if not request.user.is_authenticated(): + repos = repos.filter(staging=False) context = { 'arches': Arch.objects.all(), - 'repos': Repo.objects.all(), + 'repos': repos, } return render(request, 'public/feeds.html', context) -- cgit v1.2.3 From 45d81a9578e846062550335495dbceb82f16a1a0 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 13 Nov 2012 10:03:55 -0600 Subject: Move JSON keys view to public/ app This seems like a more appropriate place, and now the visualization is done here anyway so we should move the data backing it. Signed-off-by: Dan McGee --- public/views.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) (limited to 'public') diff --git a/public/views.py b/public/views.py index 42f2f345..96120761 100644 --- a/public/views.py +++ b/public/views.py @@ -1,12 +1,13 @@ from datetime import datetime +import json from operator import attrgetter from django.conf import settings from django.contrib.auth.models import User from django.db.models import Count, Q -from django.http import Http404 +from django.http import Http404, HttpResponse from django.shortcuts import render -from django.views.decorators.cache import cache_control +from django.views.decorators.cache import cache_control, cache_page from devel.models import MasterKey, PGPSignature from main.models import Arch, Repo, Donor @@ -14,6 +15,7 @@ from mirrors.models import MirrorUrl from news.models import News from .utils import get_recent_updates + @cache_control(max_age=300) def index(request): if request.user.is_authenticated(): @@ -44,6 +46,7 @@ USER_LISTS = { }, } + @cache_control(max_age=300) def userlist(request, user_type='devs'): users = User.objects.order_by( @@ -63,6 +66,7 @@ def userlist(request, user_type='devs'): context['users'] = users return render(request, 'public/userlist.html', context) + @cache_control(max_age=300) def donate(request): context = { @@ -70,6 +74,7 @@ def donate(request): } return render(request, 'public/donate.html', context) + @cache_control(max_age=300) def download(request): mirror_urls = MirrorUrl.objects.select_related('mirror').filter( @@ -84,6 +89,7 @@ def download(request): } return render(request, 'public/download.html', context) + @cache_control(max_age=300) def feeds(request): repos = Repo.objects.all() @@ -95,6 +101,7 @@ def feeds(request): } return render(request, 'public/feeds.html', context) + @cache_control(max_age=300) def keys(request): users = User.objects.filter(is_active=True).select_related( @@ -132,4 +139,46 @@ def keys(request): } return render(request, 'public/keys.html', context) + +@cache_page(1800) +def keys_json(request): + node_list = [] + + users = User.objects.filter(is_active=True).select_related('userprofile') + node_list.extend({ + 'name': dev.get_full_name(), + 'key': dev.userprofile.pgp_key, + 'group': 'dev' + } for dev in users.filter(groups__name='Developers')) + node_list.extend({ + 'name': tu.get_full_name(), + 'key': tu.userprofile.pgp_key, + 'group': 'tu' + } for tu in users.filter(groups__name='Trusted Users').exclude( + groups__name='Developers')) + + master_keys = MasterKey.objects.select_related('owner').filter( + revoked__isnull=True) + node_list.extend({ + 'name': 'Master Key (%s)' % key.owner.get_full_name(), + 'key': key.pgp_key, + 'group': 'master' + } for key in master_keys) + + node_list.append({ + 'name': 'CA Cert Signing Authority', + 'key': 'A31D4F81EF4EBD07B456FA04D2BB0D0165D0FD58', + 'group': 'cacert', + }) + + not_expired = Q(expires__gt=datetime.utcnow) | Q(expires__isnull=True) + signatures = PGPSignature.objects.filter(not_expired, valid=True) + edge_list = [{ 'signee': sig.signee, 'signer': sig.signer } + for sig in signatures] + + data = { 'nodes': node_list, 'edges': edge_list } + + to_json = json.dumps(data, ensure_ascii=False) + return HttpResponse(to_json, mimetype='application/json') + # vim: set ts=4 sw=4 et: -- cgit v1.2.3 From 6dd4d54bb0adbbb0f8c2b1beaa92b7a58971cf88 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Fri, 16 Nov 2012 16:20:11 -0600 Subject: Use Python 2.7 dictionary comprehension syntax Rather than the old idiom of dict((k, v) for <> in <>). Signed-off-by: Dan McGee --- public/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'public') diff --git a/public/views.py b/public/views.py index 96120761..3e15f9df 100644 --- a/public/views.py +++ b/public/views.py @@ -118,7 +118,7 @@ def keys(request): sig_counts = PGPSignature.objects.filter(not_expired, valid=True, signee__in=user_key_ids).values_list('signer').annotate( Count('signer')) - sig_counts = dict((key_id[-16:], ct) for key_id, ct in sig_counts) + sig_counts = {key_id[-16:]: ct for key_id, ct in sig_counts} for key in master_keys: key.signature_count = sig_counts.get(key.pgp_key[-16:], 0) -- cgit v1.2.3 From f7331a0eca351300685ebee494e810d8c82c35b1 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 20 Nov 2012 19:16:25 -0600 Subject: Add Release model to releng This should prevent the need for monthly template updates from Pierre and Thomas; best to just let them enter the data themselves and have it show up on the website. Signed-off-by: Dan McGee --- public/views.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'public') diff --git a/public/views.py b/public/views.py index 3e15f9df..fefe032e 100644 --- a/public/views.py +++ b/public/views.py @@ -13,6 +13,7 @@ from devel.models import MasterKey, PGPSignature from main.models import Arch, Repo, Donor from mirrors.models import MirrorUrl from news.models import News +from releng.models import Release from .utils import get_recent_updates @@ -77,12 +78,17 @@ def donate(request): @cache_control(max_age=300) def download(request): + try: + release = Release.objects.filter(available=True).latest() + except Release.DoesNotExist: + release = None mirror_urls = MirrorUrl.objects.select_related('mirror').filter( protocol__default=True, mirror__public=True, mirror__active=True, mirror__isos=True) sort_by = attrgetter('real_country.name', 'mirror.name') mirror_urls = sorted(mirror_urls, key=sort_by) context = { + 'release': release, 'releng_iso_url': settings.ISO_LIST_URL, 'releng_pxeboot_url': settings.PXEBOOT_URL, 'mirror_urls': mirror_urls, -- cgit v1.2.3 From 730ac948b5dfb70646fad96cd7bad0453b9f0cea Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Fri, 21 Dec 2012 19:11:47 -0600 Subject: Add a __unicode__ method for RecentUpdate Signed-off-by: Dan McGee --- public/utils.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'public') diff --git a/public/utils.py b/public/utils.py index bf74881a..c2838212 100644 --- a/public/utils.py +++ b/public/utils.py @@ -49,6 +49,10 @@ class RecentUpdate(object): if package.arch not in arches and not arches.add(package.arch): yield PackageStandin(package) + def __unicode__(self): + return "RecentUpdate '%s %s' <%d packages>" % ( + self.pkgbase, self.version, len(self.packages)) + @cache_function(62) def get_recent_updates(number=15, testing=True, staging=False): repos = Repo.objects.all() -- cgit v1.2.3 From e7c331d361e0b6b5c9fb498793953119afcbf741 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 27 Dec 2012 22:51:20 -0600 Subject: Fix master key signing total counts Commit 4c69911982 had an inadvertent side effect here; we need to explicitly disable ordering for the annotate() to work correctly. Signed-off-by: Dan McGee --- public/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'public') diff --git a/public/views.py b/public/views.py index fefe032e..44ceb45d 100644 --- a/public/views.py +++ b/public/views.py @@ -122,7 +122,7 @@ def keys(request): master_key_ids = frozenset(key.pgp_key[-16:] for key in master_keys) sig_counts = PGPSignature.objects.filter(not_expired, valid=True, - signee__in=user_key_ids).values_list('signer').annotate( + signee__in=user_key_ids).order_by().values_list('signer').annotate( Count('signer')) sig_counts = {key_id[-16:]: ct for key_id, ct in sig_counts} -- cgit v1.2.3 From 66850026ca934e5a09238e9033c541cdc5085a42 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sun, 13 Jan 2013 22:34:33 -0600 Subject: Use content_type and not mimetype on HttpResponse() Bug #16519 in Django deprecates mimetype, so update our code accordingly. Signed-off-by: Dan McGee --- public/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'public') diff --git a/public/views.py b/public/views.py index 44ceb45d..65b0c31f 100644 --- a/public/views.py +++ b/public/views.py @@ -185,6 +185,6 @@ def keys_json(request): data = { 'nodes': node_list, 'edges': edge_list } to_json = json.dumps(data, ensure_ascii=False) - return HttpResponse(to_json, mimetype='application/json') + return HttpResponse(to_json, content_type='application/json') # vim: set ts=4 sw=4 et: -- cgit v1.2.3 From 6f0ae6746baea657ee6d7c21ac0813a04f825443 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 14 Jan 2013 01:00:11 -0600 Subject: Drop country column from mirror table We now always look for this information at the URL level, not the mirror level. This simplifies quite a bit of code in and around the mirror views. Signed-off-by: Dan McGee --- public/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'public') diff --git a/public/views.py b/public/views.py index 65b0c31f..e15f5b89 100644 --- a/public/views.py +++ b/public/views.py @@ -85,7 +85,7 @@ def download(request): mirror_urls = MirrorUrl.objects.select_related('mirror').filter( protocol__default=True, mirror__public=True, mirror__active=True, mirror__isos=True) - sort_by = attrgetter('real_country.name', 'mirror.name') + sort_by = attrgetter('country.name', 'mirror.name') mirror_urls = sorted(mirror_urls, key=sort_by) context = { 'release': release, -- cgit v1.2.3 From cba22a378b48f1a4f185a56a21f39483595cf8a6 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Fri, 18 Jan 2013 20:01:22 -0600 Subject: Don't pull and sort mirror URLs unless we have to On the download page, the explicit sorted() call was forcing evaluation of the Django queryset, even if we never actually needed the results because the template fragment was cached. Wrap it all in a callable function which looks the same to the template, but saves us the cost of evaluation every single page view. Signed-off-by: Dan McGee --- public/views.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'public') diff --git a/public/views.py b/public/views.py index e15f5b89..3c823c9d 100644 --- a/public/views.py +++ b/public/views.py @@ -82,11 +82,16 @@ def download(request): release = Release.objects.filter(available=True).latest() except Release.DoesNotExist: release = None - mirror_urls = MirrorUrl.objects.select_related('mirror').filter( - protocol__default=True, - mirror__public=True, mirror__active=True, mirror__isos=True) - sort_by = attrgetter('country.name', 'mirror.name') - mirror_urls = sorted(mirror_urls, key=sort_by) + + def mirror_urls(): + '''In order to ensure this is lazily evaluated since we can't do + sorting at the database level, make it a callable.''' + urls = MirrorUrl.objects.select_related('mirror').filter( + protocol__default=True, + mirror__public=True, mirror__active=True, mirror__isos=True) + sort_by = attrgetter('country.name', 'mirror.name') + return sorted(urls, key=sort_by) + context = { 'release': release, 'releng_iso_url': settings.ISO_LIST_URL, -- cgit v1.2.3 From 23ef118ac129e17d251634d2ef3c88c6d74279e3 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sat, 19 Jan 2013 10:37:14 -0600 Subject: Don't redefine mirror_url function every call If we pull this out and define it at the top level once, we save the interpreter a fair amount of work. Signed-off-by: Dan McGee --- public/views.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'public') diff --git a/public/views.py b/public/views.py index 3c823c9d..22cb8759 100644 --- a/public/views.py +++ b/public/views.py @@ -76,6 +76,16 @@ def donate(request): return render(request, 'public/donate.html', context) +def _mirror_urls(): + '''In order to ensure this is lazily evaluated since we can't do + sorting at the database level, make it a callable.''' + urls = MirrorUrl.objects.select_related('mirror').filter( + protocol__default=True, + mirror__public=True, mirror__active=True, mirror__isos=True) + sort_by = attrgetter('country.name', 'mirror.name') + return sorted(urls, key=sort_by) + + @cache_control(max_age=300) def download(request): try: @@ -83,20 +93,11 @@ def download(request): except Release.DoesNotExist: release = None - def mirror_urls(): - '''In order to ensure this is lazily evaluated since we can't do - sorting at the database level, make it a callable.''' - urls = MirrorUrl.objects.select_related('mirror').filter( - protocol__default=True, - mirror__public=True, mirror__active=True, mirror__isos=True) - sort_by = attrgetter('country.name', 'mirror.name') - return sorted(urls, key=sort_by) - context = { 'release': release, 'releng_iso_url': settings.ISO_LIST_URL, 'releng_pxeboot_url': settings.PXEBOOT_URL, - 'mirror_urls': mirror_urls, + 'mirror_urls': _mirror_urls, } return render(request, 'public/download.html', context) -- cgit v1.2.3 From e969da2d40ed3256a89ff10d627a11e70a451b6a Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 31 Jan 2013 08:49:50 -0600 Subject: Run pngcrush and optipng over most static content The programs have improved a bit and found some room for optimization, especially in the static logo content. Some files were reduced in size by 50% or more. Signed-off-by: Dan McGee --- .../static/logos/archlinux-logo-black-1200dpi.png | Bin 283011 -> 131811 bytes public/static/logos/archlinux-logo-black-90dpi.png | Bin 12971 -> 8291 bytes .../static/logos/archlinux-logo-dark-1200dpi.png | Bin 291912 -> 260724 bytes public/static/logos/archlinux-logo-dark-90dpi.png | Bin 13805 -> 11178 bytes .../static/logos/archlinux-logo-light-1200dpi.png | Bin 284099 -> 251334 bytes public/static/logos/archlinux-logo-light-90dpi.png | Bin 13084 -> 11047 bytes .../static/logos/archlinux-logo-white-1200dpi.png | Bin 263771 -> 131811 bytes public/static/logos/archlinux-logo-white-90dpi.png | Bin 11870 -> 8291 bytes .../static/logos/legacy/arch-legacy-aqua-blue.png | Bin 11150 -> 10281 bytes .../static/logos/legacy/arch-legacy-aqua-white.png | Bin 9171 -> 5527 bytes public/static/logos/legacy/arch-legacy-aqua.png | Bin 7709 -> 7177 bytes public/static/logos/legacy/arch-legacy-blue1.png | Bin 6563 -> 5108 bytes public/static/logos/legacy/arch-legacy-blue2.png | Bin 4588 -> 3510 bytes .../logos/legacy/arch-legacy-noodle-blue.png | Bin 13223 -> 12231 bytes .../static/logos/legacy/arch-legacy-noodle-box.png | Bin 12060 -> 11235 bytes .../static/logos/legacy/arch-legacy-noodle-cup.png | Bin 9971 -> 9446 bytes .../logos/legacy/arch-legacy-noodle-white.png | Bin 11340 -> 9589 bytes public/static/logos/legacy/arch-legacy-ribbon1.png | Bin 11628 -> 5255 bytes public/static/logos/legacy/arch-legacy-ribbon2.png | Bin 12390 -> 5361 bytes public/static/logos/legacy/arch-legacy-ribbon3.png | Bin 15590 -> 6467 bytes public/static/logos/legacy/arch-legacy-ribbon4.png | Bin 16747 -> 6813 bytes public/static/logos/legacy/arch-legacy-ribbon5.png | Bin 4986 -> 4896 bytes public/static/logos/legacy/arch-legacy-ribbon6.png | Bin 15700 -> 6457 bytes .../static/logos/legacy/arch-legacy-wombat-lg.png | Bin 114926 -> 99457 bytes public/static/logos/legacy/arch-legacy-wombat.png | Bin 7761 -> 7102 bytes 25 files changed, 0 insertions(+), 0 deletions(-) (limited to 'public') diff --git a/public/static/logos/archlinux-logo-black-1200dpi.png b/public/static/logos/archlinux-logo-black-1200dpi.png index a3082c39..3b6b6e48 100644 Binary files a/public/static/logos/archlinux-logo-black-1200dpi.png and b/public/static/logos/archlinux-logo-black-1200dpi.png differ diff --git a/public/static/logos/archlinux-logo-black-90dpi.png b/public/static/logos/archlinux-logo-black-90dpi.png index 6948b795..528f9d62 100644 Binary files a/public/static/logos/archlinux-logo-black-90dpi.png and b/public/static/logos/archlinux-logo-black-90dpi.png differ diff --git a/public/static/logos/archlinux-logo-dark-1200dpi.png b/public/static/logos/archlinux-logo-dark-1200dpi.png index 24a5cefa..62eeba12 100644 Binary files a/public/static/logos/archlinux-logo-dark-1200dpi.png and b/public/static/logos/archlinux-logo-dark-1200dpi.png differ diff --git a/public/static/logos/archlinux-logo-dark-90dpi.png b/public/static/logos/archlinux-logo-dark-90dpi.png index f3757c61..8830fe11 100644 Binary files a/public/static/logos/archlinux-logo-dark-90dpi.png and b/public/static/logos/archlinux-logo-dark-90dpi.png differ diff --git a/public/static/logos/archlinux-logo-light-1200dpi.png b/public/static/logos/archlinux-logo-light-1200dpi.png index 79e0a0f1..d5399e9a 100644 Binary files a/public/static/logos/archlinux-logo-light-1200dpi.png and b/public/static/logos/archlinux-logo-light-1200dpi.png differ diff --git a/public/static/logos/archlinux-logo-light-90dpi.png b/public/static/logos/archlinux-logo-light-90dpi.png index 95803309..e5f4055d 100644 Binary files a/public/static/logos/archlinux-logo-light-90dpi.png and b/public/static/logos/archlinux-logo-light-90dpi.png differ diff --git a/public/static/logos/archlinux-logo-white-1200dpi.png b/public/static/logos/archlinux-logo-white-1200dpi.png index 50e700cf..4c287e32 100644 Binary files a/public/static/logos/archlinux-logo-white-1200dpi.png and b/public/static/logos/archlinux-logo-white-1200dpi.png differ diff --git a/public/static/logos/archlinux-logo-white-90dpi.png b/public/static/logos/archlinux-logo-white-90dpi.png index 86679601..3c7173bc 100644 Binary files a/public/static/logos/archlinux-logo-white-90dpi.png and b/public/static/logos/archlinux-logo-white-90dpi.png differ diff --git a/public/static/logos/legacy/arch-legacy-aqua-blue.png b/public/static/logos/legacy/arch-legacy-aqua-blue.png index 9637ce72..4bbb215d 100644 Binary files a/public/static/logos/legacy/arch-legacy-aqua-blue.png and b/public/static/logos/legacy/arch-legacy-aqua-blue.png differ diff --git a/public/static/logos/legacy/arch-legacy-aqua-white.png b/public/static/logos/legacy/arch-legacy-aqua-white.png index 25fe9001..68ae73b6 100644 Binary files a/public/static/logos/legacy/arch-legacy-aqua-white.png and b/public/static/logos/legacy/arch-legacy-aqua-white.png differ diff --git a/public/static/logos/legacy/arch-legacy-aqua.png b/public/static/logos/legacy/arch-legacy-aqua.png index 881e1709..8cc7da47 100644 Binary files a/public/static/logos/legacy/arch-legacy-aqua.png and b/public/static/logos/legacy/arch-legacy-aqua.png differ diff --git a/public/static/logos/legacy/arch-legacy-blue1.png b/public/static/logos/legacy/arch-legacy-blue1.png index 3ed6c248..403a0661 100644 Binary files a/public/static/logos/legacy/arch-legacy-blue1.png and b/public/static/logos/legacy/arch-legacy-blue1.png differ diff --git a/public/static/logos/legacy/arch-legacy-blue2.png b/public/static/logos/legacy/arch-legacy-blue2.png index 8b5b791e..809ad4f0 100644 Binary files a/public/static/logos/legacy/arch-legacy-blue2.png and b/public/static/logos/legacy/arch-legacy-blue2.png differ diff --git a/public/static/logos/legacy/arch-legacy-noodle-blue.png b/public/static/logos/legacy/arch-legacy-noodle-blue.png index b24d34cf..cf7c00ed 100644 Binary files a/public/static/logos/legacy/arch-legacy-noodle-blue.png and b/public/static/logos/legacy/arch-legacy-noodle-blue.png differ diff --git a/public/static/logos/legacy/arch-legacy-noodle-box.png b/public/static/logos/legacy/arch-legacy-noodle-box.png index 1162ed64..78d76a6a 100644 Binary files a/public/static/logos/legacy/arch-legacy-noodle-box.png and b/public/static/logos/legacy/arch-legacy-noodle-box.png differ diff --git a/public/static/logos/legacy/arch-legacy-noodle-cup.png b/public/static/logos/legacy/arch-legacy-noodle-cup.png index b4f93078..c62cceee 100644 Binary files a/public/static/logos/legacy/arch-legacy-noodle-cup.png and b/public/static/logos/legacy/arch-legacy-noodle-cup.png differ diff --git a/public/static/logos/legacy/arch-legacy-noodle-white.png b/public/static/logos/legacy/arch-legacy-noodle-white.png index a12ee21c..04c17c53 100644 Binary files a/public/static/logos/legacy/arch-legacy-noodle-white.png and b/public/static/logos/legacy/arch-legacy-noodle-white.png differ diff --git a/public/static/logos/legacy/arch-legacy-ribbon1.png b/public/static/logos/legacy/arch-legacy-ribbon1.png index fb8e7720..dba79302 100644 Binary files a/public/static/logos/legacy/arch-legacy-ribbon1.png and b/public/static/logos/legacy/arch-legacy-ribbon1.png differ diff --git a/public/static/logos/legacy/arch-legacy-ribbon2.png b/public/static/logos/legacy/arch-legacy-ribbon2.png index 66635999..eccd61be 100644 Binary files a/public/static/logos/legacy/arch-legacy-ribbon2.png and b/public/static/logos/legacy/arch-legacy-ribbon2.png differ diff --git a/public/static/logos/legacy/arch-legacy-ribbon3.png b/public/static/logos/legacy/arch-legacy-ribbon3.png index c3c00b85..df412335 100644 Binary files a/public/static/logos/legacy/arch-legacy-ribbon3.png and b/public/static/logos/legacy/arch-legacy-ribbon3.png differ diff --git a/public/static/logos/legacy/arch-legacy-ribbon4.png b/public/static/logos/legacy/arch-legacy-ribbon4.png index 33a78edf..8f0ed3a0 100644 Binary files a/public/static/logos/legacy/arch-legacy-ribbon4.png and b/public/static/logos/legacy/arch-legacy-ribbon4.png differ diff --git a/public/static/logos/legacy/arch-legacy-ribbon5.png b/public/static/logos/legacy/arch-legacy-ribbon5.png index abf7cce4..e48dc537 100644 Binary files a/public/static/logos/legacy/arch-legacy-ribbon5.png and b/public/static/logos/legacy/arch-legacy-ribbon5.png differ diff --git a/public/static/logos/legacy/arch-legacy-ribbon6.png b/public/static/logos/legacy/arch-legacy-ribbon6.png index 9f275f22..c3091240 100644 Binary files a/public/static/logos/legacy/arch-legacy-ribbon6.png and b/public/static/logos/legacy/arch-legacy-ribbon6.png differ diff --git a/public/static/logos/legacy/arch-legacy-wombat-lg.png b/public/static/logos/legacy/arch-legacy-wombat-lg.png index 0661b6f5..661ec0a9 100644 Binary files a/public/static/logos/legacy/arch-legacy-wombat-lg.png and b/public/static/logos/legacy/arch-legacy-wombat-lg.png differ diff --git a/public/static/logos/legacy/arch-legacy-wombat.png b/public/static/logos/legacy/arch-legacy-wombat.png index 67e1afac..52678145 100644 Binary files a/public/static/logos/legacy/arch-legacy-wombat.png and b/public/static/logos/legacy/arch-legacy-wombat.png differ -- cgit v1.2.3 From f579f88e174abfd0514788879fd190035b6bbf87 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 11 Mar 2013 09:23:44 -0500 Subject: Don't link to a one-element listing page from recent updates If a package is built as a split package where pkgname != pkgbase, but only one actual split package is produced, the link on the recent update screen requires an extra click to get to the single package. Fix this by linking directly to the package itself. (Examples in current repos: ntfs-3g, python2-south) Signed-off-by: Dan McGee --- public/utils.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'public') diff --git a/public/utils.py b/public/utils.py index c2838212..fcfd0f77 100644 --- a/public/utils.py +++ b/public/utils.py @@ -1,3 +1,4 @@ +from collections import defaultdict from operator import attrgetter from main.models import Arch, Repo, Package @@ -44,10 +45,14 @@ class RecentUpdate(object): else: # fake out the template- this is slightly hacky but yields one # 'package-like' object per arch which is what the normal loop does - arches = set() + by_arch = defaultdict(list) for package in self.others: - if package.arch not in arches and not arches.add(package.arch): - yield PackageStandin(package) + by_arch[package.arch].append(package) + for arch, packages in by_arch.items(): + if len(packages) == 1: + yield packages[0] + else: + yield PackageStandin(packages[0]) def __unicode__(self): return "RecentUpdate '%s %s' <%d packages>" % ( -- cgit v1.2.3