bgneal@170: """This file contains the feed class for the forums application."""
bgneal@170: 
bgneal@176: from django.contrib.syndication.views import Feed
bgneal@170: from django.core.exceptions import ObjectDoesNotExist
bgneal@176: from django.shortcuts import get_object_or_404
bgneal@170: 
bgneal@393: from forums.models import Forum, Topic, Post
bgneal@176: from core.functions import copyright_str
bgneal@170: 
bgneal@170: 
bgneal@170: class ForumsFeed(Feed):
bgneal@176:     """The Feed class for a specific forum"""
bgneal@170: 
bgneal@385:     ttl = '60'
bgneal@176:     author_name = 'Brian Neal'
bgneal@176:     author_email = 'admin@surfguitar101.com'
bgneal@176: 
bgneal@176:     def get_object(self, request, forum_slug):
bgneal@170:         # only return public forums
bgneal@176:         if forum_slug:
bgneal@176:             forum = get_object_or_404(Forum, slug=forum_slug)
bgneal@387:             if forum.id not in Forum.objects.public_forum_ids():
bgneal@170:                 raise ObjectDoesNotExist
bgneal@170:             return forum
bgneal@170: 
bgneal@176:         else:
bgneal@170:             # return None to indicate we want a combined feed
bgneal@170:             return None
bgneal@170: 
bgneal@170:     def title(self, obj):
bgneal@170:         if obj is None:
bgneal@170:             forum_name = 'Combined'
bgneal@170:         else:
bgneal@170:             forum_name = obj.name
bgneal@170: 
bgneal@170:         return 'SurfGuitar101.com %s Forum Feed' % forum_name
bgneal@170: 
bgneal@170:     def link(self, obj):
bgneal@170:         if obj is None:
bgneal@170:             bits = ''
bgneal@170:         else:
bgneal@170:             bits = obj.slug + '/'
bgneal@170: 
bgneal@170:         return '/feeds/forums/' + bits
bgneal@170: 
bgneal@170:     def description(self, obj):
bgneal@170:         if obj is None:
bgneal@170:             return "User posts to SurfGuitar101.com forums."
bgneal@170:         return obj.description
bgneal@170: 
bgneal@176:     def feed_copyright(self):
bgneal@176:         return copyright_str()
bgneal@170: 
bgneal@170:     def items(self, obj):
bgneal@170:         if obj is None:
bgneal@170:             # return a combined feed of public forum threads
bgneal@387: 
bgneal@393:             # This was tricky to do without suffering a large performance
bgneal@393:             # impact. Because the number of forums is small, MySQL did not
bgneal@393:             # try to use an index and ended up searching all the topics for
bgneal@396:             # candidate posts. We work around this by first getting a small list
bgneal@393:             # of candidate topics, and then searching them. This is more
bgneal@393:             # queries but a *lot* more time efficient.
bgneal@387: 
bgneal@393:             forum_ids = Forum.objects.public_forum_ids()
bgneal@393:             topic_ids = list(Topic.objects.filter(forum__in=forum_ids).order_by(
bgneal@393:                     '-update_date').values_list('id', flat=True)[:30])
bgneal@393:             items = Post.objects.filter(topic__in=topic_ids)
bgneal@387: 
bgneal@170:         else:
bgneal@393:             items = Post.objects.filter(topic__forum=obj)
bgneal@393: 
bgneal@393:         return items.order_by('-creation_date').select_related('topic', 'user',
bgneal@393:                 'topic__forum')[:30]
bgneal@170: 
bgneal@176:     def item_title(self, item):
bgneal@176:         return item.topic.name
bgneal@176: 
bgneal@176:     def item_description(self, item):
bgneal@176:         return item.html
bgneal@176: 
bgneal@176:     def item_author_name(self, item):
bgneal@176:         return item.user.username
bgneal@176: 
bgneal@170:     def item_pubdate(self, item):
bgneal@170:        return item.creation_date
bgneal@170: 
bgneal@170:     def item_categories(self, item):
bgneal@170:        return (item.topic.forum.name, )