changeset 170:6f14970b103a

Implement #52 Forums RSS feeds.
author Brian Neal <bgneal@gmail.com>
date Thu, 11 Feb 2010 02:29:03 +0000
parents 7071b196ddd5
children b1766b1bda45
files gpp/forums/feeds.py gpp/forums/models.py gpp/forums/views.py gpp/news/feeds.py gpp/templates/forums/feed_description.html gpp/templates/forums/feed_title.html gpp/templates/forums/index.html gpp/urls.py
diffstat 8 files changed, 142 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gpp/forums/feeds.py	Thu Feb 11 02:29:03 2010 +0000
@@ -0,0 +1,75 @@
+"""This file contains the feed class for the forums application."""
+import datetime
+
+from django.contrib.syndication.feeds import Feed
+from django.core.exceptions import ObjectDoesNotExist
+
+from forums.models import Forum
+from forums.models import Post
+
+BASE_YEAR = 2010
+
+class ForumsFeed(Feed):
+    """The Feed class for the forums application"""
+
+    def get_object(self, bits):
+        # only return public forums
+        if len(bits) == 1:
+            forum = Forum.objects.get(slug=bits[0])
+            if forum.category.groups.count() > 0:
+                raise ObjectDoesNotExist
+            return forum
+
+        elif len(bits) == 0:
+            # return None to indicate we want a combined feed
+            return None
+
+    def title(self, obj):
+        if obj is None:
+            forum_name = 'Combined'
+        else:
+            forum_name = obj.name
+
+        return 'SurfGuitar101.com %s Forum Feed' % forum_name
+
+    def link(self, obj):
+        if obj is None:
+            bits = ''
+        else:
+            bits = obj.slug + '/'
+
+        return '/feeds/forums/' + bits
+
+    def description(self, obj):
+        if obj is None:
+            return "User posts to SurfGuitar101.com forums."
+        return obj.description
+
+    def copyright(self):
+        curr_year = datetime.datetime.now().year
+        if curr_year == BASE_YEAR:
+            year_range = str(BASE_YEAR)
+        else:
+            year_range = "%d - %d" % (BASE_YEAR, curr_year)
+
+        return 'Copyright (C) %s, SurfGuitar101.com' % year_range
+
+    ttl = '720'
+
+    title_template = 'forums/feed_title.html'
+    description_template = 'forums/feed_description.html'
+    
+    def items(self, obj):
+        if obj is None:
+            # return a combined feed of public forum threads
+            items = Post.objects.filter(
+                    topic__forum__in=Forum.objects.public_forums())
+        else:
+            items = Post.objects.filter(topic__forum__id=obj.id)
+        return items.order_by('-creation_date').select_related()[:10]
+
+    def item_pubdate(self, item):
+       return item.creation_date
+
+    def item_categories(self, item):
+       return (item.topic.forum.name, )
--- a/gpp/forums/models.py	Sun Jan 31 04:52:08 2010 +0000
+++ b/gpp/forums/models.py	Thu Feb 11 02:29:03 2010 +0000
@@ -42,6 +42,10 @@
             return self.groups.filter(user__pk=user.id).count() > 0
         return False
 
+    def is_public(self):
+        """Returns true if this is a public category, viewable by all."""
+        return self.groups.count() == 0
+
 
 class ForumManager(models.Manager):
     """
@@ -62,6 +66,10 @@
         qs = self._for_user(user)
         return qs.values_list('id', flat=True)
 
+    def public_forums(self):
+        """Returns a queryset containing the public forums."""
+        return self.filter(category__groups__isnull=True)
+
     def _for_user(self, user):
         """Common code for the xxx_for_user() methods."""
         if user.is_superuser:
--- a/gpp/forums/views.py	Sun Jan 31 04:52:08 2010 +0000
+++ b/gpp/forums/views.py	Thu Feb 11 02:29:03 2010 +0000
@@ -82,10 +82,20 @@
     elif query == "mine":
         return redirect('forums-my_posts')
 
+    public_forums = Forum.objects.public_forums()
+    feeds = [{'name': 'All Forums', 'feed': '/feeds/forums/'}]
+
     forums = Forum.objects.forums_for_user(request.user)
     get_forum_unread_status(forums, request.user)
     cats = {}
     for forum in forums:
+        forum.has_feed = forum in public_forums
+        if forum.has_feed:
+            feeds.append({
+                'name': '%s Forum' % forum.name,
+                'feed': '/feeds/forums/%s/' % forum.slug,
+                })
+
         cat = cats.setdefault(forum.category.id, {
             'cat': forum.category,
             'forums': [],
@@ -97,6 +107,7 @@
 
     return render_to_response('forums/index.html', {
         'cats': cats,
+        'feeds': feeds,
         },
         context_instance=RequestContext(request))
 
--- a/gpp/news/feeds.py	Sun Jan 31 04:52:08 2010 +0000
+++ b/gpp/news/feeds.py	Thu Feb 11 02:29:03 2010 +0000
@@ -1,28 +1,40 @@
 """
 This file contains the feed classes for the news application.
 """
+import datetime
 
 from django.contrib.syndication.feeds import Feed
+
 from news.models import Story
 
+BASE_YEAR = 2010
+
 
 class LatestNewsFeed(Feed):
-   """The Feed class for the news application"""
+    """The Feed class for the news application"""
 
-   title = 'SurfGuitar101.com News Feed'
-   link = '/feeds/news/'
-   description = 'News articles and stories from SurfGuitar101.com'
-   copyright = 'Copyright (C) 2008, Brian Neal'
-   ttl = '720'
+    title = 'SurfGuitar101.com News Feed'
+    link = '/feeds/news/'
+    description = 'News articles and stories from SurfGuitar101.com'
+    ttl = '720'
 
-   title_template = 'news/feed_title.html'
-   description_template = 'news/feed_description.html'
-   
-   def items(self):
-      return Story.objects.order_by('-date_published')[:5]
+    title_template = 'news/feed_title.html'
+    description_template = 'news/feed_description.html'
 
-   def item_pubdate(self, item):
-      return item.date_published
+    def copyright(self):
+        curr_year = datetime.datetime.now().year
+        if curr_year == BASE_YEAR:
+            year_range = str(BASE_YEAR)
+        else:
+            year_range = "%d - %d" % (BASE_YEAR, curr_year)
 
-   def item_categories(self, item):
-      return (item.category.title, )
+        return 'Copyright (C) %s, SurfGuitar101.com' % year_range
+    
+    def items(self):
+        return Story.objects.order_by('-date_published')[:5]
+
+    def item_pubdate(self, item):
+        return item.date_published
+
+    def item_categories(self, item):
+        return (item.category.title, )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gpp/templates/forums/feed_description.html	Thu Feb 11 02:29:03 2010 +0000
@@ -0,0 +1,1 @@
+{{ obj.html|safe }}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gpp/templates/forums/feed_title.html	Thu Feb 11 02:29:03 2010 +0000
@@ -0,0 +1,1 @@
+{{ obj.topic.name }}
--- a/gpp/templates/forums/index.html	Sun Jan 31 04:52:08 2010 +0000
+++ b/gpp/templates/forums/index.html	Thu Feb 11 02:29:03 2010 +0000
@@ -1,9 +1,14 @@
 {% extends 'base.html' %}
 {% load cache %}
 {% load forum_tags %}
+{% block custom_head %}
+{% for feed in feeds %}
+<link rel="alternate" type="application/rss+xml" title="{{ feed.name }}" href="{{ feed.feed }}" />
+{% endfor %}
+{% endblock %}
 {% block title %}Forums{% endblock %}
 {% block content %}
-<h2>Forums</h2>
+<h2>Forums <a href="/feeds/forums/"><img src="{{ MEDIA_URL }}icons/feed.png" alt="Forums Feed" title="Forums Feed" /></a></h2>
 
 <form action="." method="get" id="forum-query-form">
    <select name="query">
@@ -32,7 +37,11 @@
                   {% if forum.has_unread %}
                   <img src="{{ MEDIA_URL }}icons/new.png" alt="New Posts" title="New Posts" class="forums-topic-icon" />
                   {% endif %}
-                  <h4><a href="{{ forum.get_absolute_url }}">{{ forum.name }}</a></h4>
+                  <h4><a href="{{ forum.get_absolute_url }}">{{ forum.name }}</a>
+                     {% if forum.has_feed %}
+                     <a href="/feeds/forums/{{ forum.slug }}">
+                        <img src="{{ MEDIA_URL }}icons/feed.png" alt="RSS Feed" title="Feed for this forum" /></a>
+                     {% endif %}</h4>
                   <p>{{ forum.description }}</p></td>
                <td class="forum-topics">{{ forum.topic_count }}</td>
                <td class="forum-posts">{{ forum.post_count }}</td>
--- a/gpp/urls.py	Sun Jan 31 04:52:08 2010 +0000
+++ b/gpp/urls.py	Thu Feb 11 02:29:03 2010 +0000
@@ -1,13 +1,18 @@
 from django.conf.urls.defaults import *
 from django.conf import settings
 from django.contrib import admin
+from django.views.decorators.cache import cache_page
+from django.contrib.syndication.views import feed as syndication_feed
+
 from news.feeds import LatestNewsFeed
+from forums.feeds import ForumsFeed
 
 
 admin.autodiscover()
 
 feeds = {
    'news': LatestNewsFeed,
+   'forums': ForumsFeed,
 }
 
 urlpatterns = patterns('',
@@ -21,9 +26,9 @@
    (r'^core/', include('core.urls')),
    (r'^donations/', include('donations.urls')),
    (r'^downloads/', include('downloads.urls')),
-   url(r'^feeds/(?P<url>.*)/$', 
-      'django.contrib.syndication.views.feed', 
-      {'feed_dict': feeds },
+   url(r'^feeds/(?P<url>.*)/$',
+      cache_page(syndication_feed, 60 * 15),
+      {'feed_dict': feeds},
       'feeds-news'),
    (r'^forums/', include('forums.urls')),
    (r'^irc/', include('irc.urls')),