comparison gpp/forums/feeds.py @ 509:248dd8dd67f8

For #237, use Redis as the source of posts for the RSS feeds to hopefully eliminate some slow queries.
author Brian Neal <bgneal@gmail.com>
date Wed, 07 Dec 2011 01:08:54 +0000
parents 63e4682d6482
children
comparison
equal deleted inserted replaced
508:6f5fff924877 509:248dd8dd67f8
1 """This file contains the feed class for the forums application.""" 1 """
2 This file contains the feed class for the forums application.
2 3
4 """
3 from django.contrib.syndication.views import Feed 5 from django.contrib.syndication.views import Feed
4 from django.core.exceptions import ObjectDoesNotExist 6 from django.core.exceptions import ObjectDoesNotExist
5 from django.shortcuts import get_object_or_404 7 from django.shortcuts import get_object_or_404
6 8
7 from forums.models import Forum, Topic, Post 9 from forums.models import Forum, Topic, Post
8 from core.functions import copyright_str 10 from core.functions import copyright_str
11 from forums.latest import get_latest_posts
9 12
10 13
11 class ForumsFeed(Feed): 14 class ForumsFeed(Feed):
12 """The Feed class for a specific forum""" 15 """The Feed class for a specific forum"""
13 16
14 ttl = '60' 17 ttl = '60'
15 author_name = 'Brian Neal' 18 author_name = 'Brian Neal'
16 author_email = 'admin@surfguitar101.com' 19 author_email = 'admin@surfguitar101.com'
17 20
18 def get_object(self, request, forum_slug): 21 def get_object(self, request, forum_slug):
19 # only return public forums 22
20 if forum_slug: 23 if forum_slug:
21 forum = get_object_or_404(Forum, slug=forum_slug) 24 forum = Forum.objects.get(slug=forum_slug)
25 # only return public forums
22 if forum.id not in Forum.objects.public_forum_ids(): 26 if forum.id not in Forum.objects.public_forum_ids():
23 raise ObjectDoesNotExist 27 raise ObjectDoesNotExist
24 return forum 28 return forum
25 29
26 else: 30 else:
50 54
51 def feed_copyright(self): 55 def feed_copyright(self):
52 return copyright_str() 56 return copyright_str()
53 57
54 def items(self, obj): 58 def items(self, obj):
55 if obj is None: 59 forum_id = obj.id if obj else None
56 # return a combined feed of public forum threads 60 return get_latest_posts(forum_id=forum_id)
57
58 # This was tricky to do without suffering a large performance
59 # impact. Because the number of forums is small, MySQL did not
60 # try to use an index and ended up searching all the topics for
61 # candidate posts. We work around this by first getting a small list
62 # of candidate topics, and then searching them. This is more
63 # queries but a *lot* more time efficient.
64
65 forum_ids = Forum.objects.public_forum_ids()
66 topic_ids = list(Topic.objects.filter(forum__in=forum_ids).order_by(
67 '-update_date').values_list('id', flat=True)[:30])
68 items = Post.objects.filter(topic__in=topic_ids)
69
70 else:
71 items = Post.objects.filter(topic__forum=obj)
72
73 return items.order_by('-creation_date').select_related('topic', 'user',
74 'topic__forum')[:30]
75 61
76 def item_title(self, item): 62 def item_title(self, item):
77 return item.topic.name 63 return item['title']
78 64
79 def item_description(self, item): 65 def item_description(self, item):
80 return item.html 66 return item['content']
81 67
82 def item_author_name(self, item): 68 def item_author_name(self, item):
83 return item.user.username 69 return item['author']
84 70
85 def item_pubdate(self, item): 71 def item_pubdate(self, item):
86 return item.creation_date 72 return item['pubdate']
87 73
88 def item_categories(self, item): 74 def item_categories(self, item):
89 return (item.topic.forum.name, ) 75 return [item['forum_name']]
76
77 def item_link(self, item):
78 return item['url']