summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2015-04-13 21:06:39 -0400
committerLuke Shumaker <lukeshu@sbcglobal.net>2015-04-13 21:06:39 -0400
commitc910b9220c45eb9d493d260f325efda2141205a4 (patch)
tree6152b43ea4c60a514949238b76e549fd283b9a72
parent02ffa37f8607634e5e4eccba7ef25d4f48b29b3b (diff)
parentf9f8683799ef96904a7165adcfdeb0d13cb7ff61 (diff)
Merge tag 'release_2014-10-20' into archweb-generic
A few Jinja2 fixes and some perf changes
-rw-r--r--devel/utils.py2
-rw-r--r--feeds.py22
-rw-r--r--main/models.py6
-rw-r--r--main/templatetags/pgp.py2
-rw-r--r--main/utils.py42
-rw-r--r--mirrors/views.py5
-rw-r--r--news/models.py7
-rw-r--r--packages/views/__init__.py4
-rw-r--r--public/views.py14
-rw-r--r--templates/feeds/news_description.html2
-rw-r--r--templates/feeds/packages_title.html1
-rw-r--r--templates/packages/details.html.jinja2
-rw-r--r--urls.py17
13 files changed, 42 insertions, 84 deletions
diff --git a/devel/utils.py b/devel/utils.py
index 7dd64972..eaa7d07e 100644
--- a/devel/utils.py
+++ b/devel/utils.py
@@ -10,7 +10,7 @@ from main.utils import cache_function
from main.models import Package
from packages.models import PackageRelation
-@cache_function(300)
+@cache_function(283)
def get_annotated_maintainers():
maintainers = User.objects.filter(is_active=True).order_by(
'first_name', 'last_name')
diff --git a/feeds.py b/feeds.py
index 6a17949c..a7b7120c 100644
--- a/feeds.py
+++ b/feeds.py
@@ -5,11 +5,11 @@ from pytz import utc
from django.conf import settings
from django.contrib.sites.models import Site
from django.contrib.syndication.views import Feed
+from django.db import connection
from django.db.models import Q
from django.utils.feedgenerator import Rss201rev2Feed
from django.views.decorators.http import condition
-from main.utils import retrieve_latest
from main.models import Arch, Repo, Package
from news.models import News
from releng.models import Release
@@ -65,20 +65,21 @@ class GuidNotPermalinkFeed(Rss201rev2Feed):
def package_etag(request, *args, **kwargs):
- latest = retrieve_latest(Package)
+ latest = package_last_modified(request)
if latest:
return hashlib.md5(str(kwargs) + str(latest)).hexdigest()
return None
def package_last_modified(request, *args, **kwargs):
- return retrieve_latest(Package)
+ cursor = connection.cursor()
+ cursor.execute("SELECT MAX(last_update) FROM packages")
+ return cursor.fetchone()[0]
class PackageFeed(Feed):
feed_type = GuidNotPermalinkFeed
link = '/packages/'
- title_template = 'feeds/packages_title.html'
def __call__(self, request, *args, **kwargs):
wrapper = condition(etag_func=package_etag, last_modified_func=package_last_modified)
@@ -141,6 +142,9 @@ class PackageFeed(Feed):
def item_pubdate(self, item):
return item.last_update
+ def item_title(self, item):
+ return '%s %s %s' % (item.pkgname, item.full_version, item.arch.name)
+
def item_description(self, item):
return item.pkgdesc
@@ -149,13 +153,15 @@ class PackageFeed(Feed):
def news_etag(request, *args, **kwargs):
- latest = retrieve_latest(News, 'last_modified')
+ latest = news_last_modified(request)
if latest:
return hashlib.md5(str(latest)).hexdigest()
return None
def news_last_modified(request, *args, **kwargs):
- return retrieve_latest(News, 'last_modified')
+ cursor = connection.cursor()
+ cursor.execute("SELECT MAX(last_modified) FROM news")
+ return cursor.fetchone()[0]
class NewsFeed(Feed):
@@ -165,7 +171,6 @@ class NewsFeed(Feed):
link = '/news/'
description = 'The latest and greatest news from the '+settings.BRANDING_DISTRONAME+' distribution.'
subtitle = description
- description_template = 'feeds/news_description.html'
def __call__(self, request, *args, **kwargs):
wrapper = condition(etag_func=news_etag, last_modified_func=news_last_modified)
@@ -189,6 +194,9 @@ class NewsFeed(Feed):
def item_title(self, item):
return item.title
+ def item_description(self, item):
+ return item.html()
+
class ReleaseFeed(Feed):
feed_type = GuidNotPermalinkFeed
diff --git a/main/models.py b/main/models.py
index 09b1adc0..1b95f3fa 100644
--- a/main/models.py
+++ b/main/models.py
@@ -443,12 +443,8 @@ class PackageFile(models.Model):
db_table = 'package_files'
-# connect signals needed to keep cache in line with reality
-from main.utils import refresh_latest
-from django.db.models.signals import pre_save, post_save
+from django.db.models.signals import pre_save
-post_save.connect(refresh_latest, sender=Package,
- dispatch_uid="main.models")
# note: reporead sets the 'created' field on Package objects, so no signal
# listener is set up here to do so
pre_save.connect(set_created_field, sender=Donor,
diff --git a/main/templatetags/pgp.py b/main/templatetags/pgp.py
index cc080439..2417f688 100644
--- a/main/templatetags/pgp.py
+++ b/main/templatetags/pgp.py
@@ -44,7 +44,7 @@ def pgp_key_link(key_id, link_text=None):
return '<a href="%s" title="PGP key search for %s">%s</a>' % values
-@cache_function(1800)
+@cache_function(1741)
def name_for_key(normalized):
try:
matching_key = DeveloperKey.objects.select_related(
diff --git a/main/utils.py b/main/utils.py
index 97cc540a..cf156566 100644
--- a/main/utils.py
+++ b/main/utils.py
@@ -12,11 +12,6 @@ from django.utils.timezone import now
from django.template.defaultfilters import slugify
-CACHE_TIMEOUT = 1800
-INVALIDATE_TIMEOUT = 10
-CACHE_LATEST_PREFIX = 'cache_latest_'
-
-
def cache_function_key(func, args, kwargs):
raw = [func.__name__, func.__module__, args, kwargs]
pickled = pickle.dumps(raw, protocol=pickle.HIGHEST_PROTOCOL)
@@ -76,43 +71,6 @@ def format_http_headers(request):
make_choice = lambda l: [(str(m), str(m)) for m in l]
-# These are in here because we would be jumping around in some import circles
-# and hoops otherwise. The only thing currently using these keys is the feed
-# caching stuff.
-
-def refresh_latest(**kwargs):
- '''A post_save signal handler to clear out the cached latest value for a
- given model.'''
- cache_key = CACHE_LATEST_PREFIX + kwargs['sender'].__name__
- # We could delete the value, but that could open a race condition
- # where the new data wouldn't have been committed yet by the calling
- # thread. Instead, explicitly set it to None for a short amount of time.
- # Hopefully by the time it expires we will have committed, and the cache
- # will be valid again. See "Scaling Django" by Mike Malone, slide 30.
- cache.set(cache_key, None, INVALIDATE_TIMEOUT)
-
-
-def retrieve_latest(sender, latest_by=None):
- # we could break this down based on the request url, but it would probably
- # cost us more in query time to do so.
- cache_key = CACHE_LATEST_PREFIX + sender.__name__
- latest = cache.get(cache_key)
- if latest:
- return latest
- try:
- if latest_by is None:
- latest_by = sender._meta.get_latest_by
- latest = sender.objects.values(latest_by).latest(latest_by)[latest_by]
- # Using add means "don't overwrite anything in there". What could be in
- # there is an explicit None value that our refresh signal set, which
- # means we want to avoid race condition possibilities for a bit.
- cache.add(cache_key, latest, CACHE_TIMEOUT)
- return latest
- except sender.DoesNotExist:
- pass
- return None
-
-
def set_created_field(sender, **kwargs):
'''This will set the 'created' field on any object to the current UTC time
if it is unset.
diff --git a/mirrors/views.py b/mirrors/views.py
index 26b5b802..55c40c4d 100644
--- a/mirrors/views.py
+++ b/mirrors/views.py
@@ -6,6 +6,7 @@ from operator import attrgetter, itemgetter
from django import forms
from django.forms.widgets import CheckboxSelectMultiple
from django.core.serializers.json import DjangoJSONEncoder
+from django.db import connection
from django.db.models import Q
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, redirect, render
@@ -222,7 +223,9 @@ def url_details(request, name, url_id):
def status_last_modified(request, *args, **kwargs):
- return MirrorLog.objects.values_list('check_time', flat=True).latest()
+ cursor = connection.cursor()
+ cursor.execute("SELECT MAX(check_time) FROM mirrors_mirrorlog")
+ return cursor.fetchone()[0]
@condition(last_modified_func=status_last_modified)
diff --git a/news/models.py b/news/models.py
index d51db7c7..985c1088 100644
--- a/news/models.py
+++ b/news/models.py
@@ -45,12 +45,9 @@ def set_news_fields(sender, **kwargs):
news.guid = 'tag:%s,%s:%s' % (Site.objects.get_current(),
current_time.strftime('%Y-%m-%d'), news.get_absolute_url())
-# connect signals needed to keep cache in line with reality
-from main.utils import refresh_latest
-from django.db.models.signals import pre_save, post_save
-post_save.connect(refresh_latest, sender=News,
- dispatch_uid="news.models")
+from django.db.models.signals import pre_save
+
pre_save.connect(set_news_fields, sender=News,
dispatch_uid="news.models")
diff --git a/packages/views/__init__.py b/packages/views/__init__.py
index 46c99985..6b44206a 100644
--- a/packages/views/__init__.py
+++ b/packages/views/__init__.py
@@ -35,7 +35,7 @@ def opensearch(request):
@require_safe
-@cache_control(public=True, max_age=300)
+@cache_control(public=True, max_age=613)
def opensearch_suggest(request):
search_term = request.GET.get('q', '')
if search_term == '':
@@ -55,7 +55,7 @@ def opensearch_suggest(request):
'pkgname', flat=True).order_by('pkgname').distinct()[:10]
results = [search_term, list(names)]
to_json = json.dumps(results, ensure_ascii=False)
- cache.set(cache_key, to_json, 300)
+ cache.set(cache_key, to_json, 613)
return HttpResponse(to_json, content_type='application/x-suggestions+json')
diff --git a/public/views.py b/public/views.py
index d1661afd..4ddcef1e 100644
--- a/public/views.py
+++ b/public/views.py
@@ -17,7 +17,7 @@ from releng.models import Release
from .utils import get_recent_updates
-@cache_control(max_age=300)
+@cache_control(max_age=307)
def index(request):
if request.user.is_authenticated():
def updates():
@@ -50,7 +50,7 @@ USER_LISTS = {
}
-@cache_control(max_age=300)
+@cache_control(max_age=307)
def userlist(request, user_type='devs'):
users = User.objects.order_by(
'first_name', 'last_name').select_related('userprofile')
@@ -70,7 +70,7 @@ def userlist(request, user_type='devs'):
return render(request, 'public/userlist.html', context)
-@cache_control(max_age=300)
+@cache_control(max_age=307)
def donate(request):
context = {
'donors': Donor.objects.filter(visible=True).order_by('name'),
@@ -88,7 +88,7 @@ def _mirror_urls():
return sorted(urls, key=sort_by)
-@cache_control(max_age=300)
+@cache_control(max_age=307)
def download(request):
try:
release = Release.objects.filter(available=True).latest()
@@ -104,7 +104,7 @@ def download(request):
return render(request, 'public/download.html', context)
-@cache_control(max_age=300)
+@cache_control(max_age=307)
def feeds(request):
repos = Repo.objects.all()
if not request.user.is_authenticated():
@@ -116,7 +116,7 @@ def feeds(request):
return render(request, 'public/feeds.html', context)
-@cache_control(max_age=300)
+@cache_control(max_age=307)
def keys(request):
users = User.objects.filter(is_active=True).select_related(
'userprofile__pgp_key').order_by('first_name', 'last_name')
@@ -153,7 +153,7 @@ def keys(request):
return render(request, 'public/keys.html', context)
-@cache_page(1800)
+@cache_page(1789)
def keys_json(request):
node_list = []
diff --git a/templates/feeds/news_description.html b/templates/feeds/news_description.html
deleted file mode 100644
index 61ceedf3..00000000
--- a/templates/feeds/news_description.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<p>{{obj.author.get_full_name}} wrote:</p>
-{{ obj.html }}
diff --git a/templates/feeds/packages_title.html b/templates/feeds/packages_title.html
deleted file mode 100644
index f92ac684..00000000
--- a/templates/feeds/packages_title.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ obj.pkgname }} {{ obj.full_version }} {{ obj.arch.name }} \ No newline at end of file
diff --git a/templates/packages/details.html.jinja b/templates/packages/details.html.jinja
index 3632ecf0..af4cbe24 100644
--- a/templates/packages/details.html.jinja
+++ b/templates/packages/details.html.jinja
@@ -183,7 +183,7 @@
<th>Last Updated:</th>
<td>{{ pkg.last_update|date("DATETIME_FORMAT") }} UTC</td>
</tr>
- {% if user.is_authenticated %}{% with flag_request = pkg.flag_request() %}{% if flag_request %}<tr>
+ {% if user.is_authenticated() %}{% with flag_request = pkg.flag_request() %}{% if flag_request %}<tr>
<th>Last Flag Request:</th>
<td class="wrap">From {{ flag_request.who() }} on {{ flag_request.created|date }}:<br/>
<div class="userdata">{{ flag_request.message|linebreaksbr|default("{no message}") }}</div></td>
diff --git a/urls.py b/urls.py
index e7f2b24c..8f0bbe21 100644
--- a/urls.py
+++ b/urls.py
@@ -41,20 +41,19 @@ urlpatterns += patterns('public.views',
# Feeds patterns, used below
feeds_patterns = patterns('',
(r'^$', 'public.views.feeds', {}, 'feeds-list'),
- (r'^news/$', cache_page(300)(NewsFeed())),
- (r'^packages/$', cache_page(300)(PackageFeed())),
+ (r'^news/$', cache_page(311)(NewsFeed())),
+ (r'^packages/$', cache_page(313)(PackageFeed())),
(r'^packages/(?P<arch>[A-z0-9]+)/$',
- cache_page(300)(PackageFeed())),
+ cache_page(313)(PackageFeed())),
(r'^packages/all/(?P<repo>[A-z0-9\-]+)/$',
- cache_page(300)(PackageFeed())),
+ cache_page(313)(PackageFeed())),
(r'^packages/(?P<arch>[A-z0-9]+)/(?P<repo>[A-z0-9\-]+)/$',
- cache_page(300)(PackageFeed())),
- (r'^releases/$', cache_page(300)(ReleaseFeed())),
+ cache_page(313)(PackageFeed())),
+ (r'^releases/$', cache_page(317)(ReleaseFeed())),
)
# Includes and other remaining stuff
urlpatterns += patterns('',
- # cache this static JS resource for 1 week rather than default 5 minutes
(r'^admin/', include(admin.site.urls)),
(r'^devel/', include('devel.urls')),
(r'^feeds/', include(feeds_patterns)),
@@ -80,10 +79,10 @@ urlpatterns += patterns('retro.views',
# Sitemaps
urlpatterns += patterns('',
(r'^sitemap.xml$',
- cache_page(1800)(sitemap_views.index),
+ cache_page(1831)(sitemap_views.index),
{'sitemaps': our_sitemaps, 'sitemap_url_name': 'sitemaps'}),
(r'^sitemap-(?P<section>.+)\.xml$',
- cache_page(1800)(sitemap_views.sitemap),
+ cache_page(1831)(sitemap_views.sitemap),
{'sitemaps': our_sitemaps}, 'sitemaps'),
)