summaryrefslogtreecommitdiffstats
path: root/feeds.py
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2010-09-14 17:42:12 -0500
committerDan McGee <dan@archlinux.org>2010-09-14 17:42:12 -0500
commit5dc5688d971824f7ccc38c0d5f85f60743424c39 (patch)
tree2f1b83bc8f51eb007b4ebba477d75bc5d8b9d039 /feeds.py
parent6c54cdb9ca72c8745d76fe2d3db11197c9eb104d (diff)
downloadarchweb-5dc5688d971824f7ccc38c0d5f85f60743424c39.tar.gz
archweb-5dc5688d971824f7ccc38c0d5f85f60743424c39.zip
Improve request handling for feeds that haven't changed
By using the condition decorator (in a slightly odd way because these are class-based views), we can cut down a lot on the response time for returning 304 status code for feeds that haven't changed. The decorator means we no longer have to completely render the view to see if we can return a 304 status code. Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'feeds.py')
-rw-r--r--feeds.py37
1 files changed, 37 insertions, 0 deletions
diff --git a/feeds.py b/feeds.py
index c6395f87..ac85c72b 100644
--- a/feeds.py
+++ b/feeds.py
@@ -2,15 +2,36 @@ import datetime
from django.contrib.syndication.views import Feed
from django.db.models import Q
+from django.utils.hashcompat import md5_constructor
+from django.views.decorators.http import condition
from main.models import Arch, Repo, Package
from news.models import News
+def package_etag(request, *args, **kwargs):
+ latest = Package.objects.latest('last_update')
+ if latest:
+ return md5_constructor(
+ str(kwargs) + str(latest.last_update)).hexdigest()
+ return None
+
+def package_last_modified(request, *args, **kwargs):
+ # we could break this down based on the request url, but it would probably
+ # cost us more in query time to do so.
+ latest = Package.objects.latest('last_update')
+ if latest:
+ return latest.last_update
+ return None
+
class PackageFeed(Feed):
link = '/packages/'
title_template = 'feeds/packages_title.html'
description_template = 'feeds/packages_description.html'
+ def __call__(self, request, *args, **kwargs):
+ wrapper = condition(etag_func=package_etag, last_modified_func=package_last_modified)
+ return wrapper(super(PackageFeed, self).__call__)(request, *args, **kwargs)
+
def get_object(self, request, arch='', repo=''):
obj = dict()
qs = Package.objects.select_related('arch', 'repo').order_by('-last_update')
@@ -57,6 +78,18 @@ class PackageFeed(Feed):
return (item.repo.name, item.arch.name)
+def news_etag(request, *args, **kwargs):
+ latest = News.objects.latest('last_modified')
+ if latest:
+ return md5_constructor(str(latest.last_modified)).hexdigest()
+ return None
+
+def news_last_modified(request):
+ latest = News.objects.latest('last_modified')
+ if latest:
+ return latest.last_modified
+ return None
+
class NewsFeed(Feed):
title = 'Arch Linux: Recent news updates'
link = '/news/'
@@ -64,6 +97,10 @@ class NewsFeed(Feed):
title_template = 'feeds/news_title.html'
description_template = 'feeds/news_description.html'
+ def __call__(self, request, *args, **kwargs):
+ wrapper = condition(etag_func=news_etag, last_modified_func=news_last_modified)
+ return wrapper(super(NewsFeed, self).__call__)(request, *args, **kwargs)
+
def items(self):
return News.objects.select_related('author').order_by('-postdate', '-id')[:10]