view gpp/forums/views.py @ 93:4c33e266db03

Forums: paginate the topic list inside a forum.
author Brian Neal <bgneal@gmail.com>
date Sun, 13 Sep 2009 04:33:15 +0000
parents 62af8cd8f57b
children 96eec1ed0fd3
line wrap: on
line source
"""
Views for the forums application.
"""
from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.http import HttpResponseBadRequest
from django.http import HttpResponseForbidden
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.core.paginator import InvalidPage
from django.shortcuts import get_object_or_404
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.decorators.http import require_POST

from core.paginator import DiggPaginator
from forums.models import Forum
from forums.models import Topic
from forums.models import Post
from forums.forms import NewTopicForm
from forums.forms import PostForm

#######################################################################

TOPICS_PER_PAGE = 50
POSTS_PER_PAGE = 2

def create_topic_paginator(topics):
   return DiggPaginator(topics, TOPICS_PER_PAGE, body=5, tail=2, margin=3, padding=2)

def create_post_paginator(posts):
   return DiggPaginator(posts, POSTS_PER_PAGE, body=5, tail=2, margin=3, padding=2)

#######################################################################

def index(request):
    """
    This view displays all the forums available, ordered in each category.
    """
    forums = Forum.objects.all().select_related()
    cats = {}
    for forum in forums:
        cat = cats.setdefault(forum.category.id, {
            'cat': forum.category,
            'forums': [],
            })
        cat['forums'].append(forum)

    cmpdef = lambda a, b: cmp(a['cat'].position, b['cat'].position)
    cats = sorted(cats.values(), cmpdef)

    return render_to_response('forums/index.html', {
        'cats': cats,
        },
        context_instance=RequestContext(request))


def forum_index(request, slug):
    """
    Displays all the topics in a forum.
    """
    forum = get_object_or_404(Forum, slug=slug)
    topics = forum.topics.select_related()
    paginator = create_topic_paginator(topics)
    page_num = int(request.GET.get('page', 1))
    try:
        page = paginator.page(page_num)
    except InvalidPage:
        raise Http404
    
    return render_to_response('forums/forum_index.html', {
        'forum': forum,
        'page': page,
        },
        context_instance=RequestContext(request))


def topic_index(request, id):
    """
    Displays all the posts in a topic.
    """
    topic = get_object_or_404(Topic, pk=id)
    topic.view_count += 1
    topic.save()

    posts = topic.posts.select_related()
    paginator = create_post_paginator(posts)
    page_num = int(request.GET.get('page', 1))
    try:
        page = paginator.page(page_num)
    except InvalidPage:
        raise Http404

    last_page = page_num == paginator.num_pages

    return render_to_response('forums/topic.html', {
        'forum': topic.forum,
        'topic': topic,
        'page': page,
        'last_page': last_page,
        'form': PostForm(initial={'topic_id': topic.id}),
        },
        context_instance=RequestContext(request))


@login_required
def new_topic(request, slug):
    """
    This view handles the creation of new topics.
    """
    forum = get_object_or_404(Forum, slug=slug)
    if request.method == 'POST':
        form = NewTopicForm(request.POST)
        if form.is_valid():
            topic = form.save(forum, request.user, request.META.get("REMOTE_ADDR"))
            return HttpResponseRedirect(reverse('forums-new_topic_thanks',
                                            kwargs={'tid': topic.pk}))
    else:
        form = NewTopicForm()
    
    return render_to_response('forums/new_topic.html', {
        'forum': forum,
        'form': form,
        },
        context_instance=RequestContext(request))


@login_required
def new_topic_thanks(request, tid):
    """
    This view displays the success page for a newly created topic.
    """
    topic = get_object_or_404(Topic, pk=tid)
    return render_to_response('forums/new_topic_thanks.html', {
        'forum': topic.forum,
        'topic': topic,
        },
        context_instance=RequestContext(request))


@require_POST
def quick_reply_ajax(request):
    """
    This function handles the quick reply to a thread function. This
    function is meant to be the target of an AJAX post, and returns
    the HTML for the new post, which the client-side script appends
    to the document.
    """
    if not request.user.is_authenticated():
        return HttpResponseForbidden()

    form = PostForm(request.POST)
    if form.is_valid():
        post = form.save(request.user, request.META.get("REMOTE_ADDR"))
        return render_to_response('forums/display_post.html', {
            'post': post,
            },
            context_instance=RequestContext(request))

    return HttpResponseBadRequest();


def goto_post(request, post_id):
    """
    This function calculates what page a given post is on, then redirects
    to that URL. This function is the target of get_absolute_url() for
    Post objects.
    """
    post = get_object_or_404(Post, pk=post_id)
    count = post.topic.posts.filter(creation_date__lt=post.creation_date).count()
    page = count / POSTS_PER_PAGE + 1
    url = reverse('forums-topic_index', kwargs={'id': post.topic.id}) + \
        '?page=%s#p%s' % (page, post.id)
    return HttpResponseRedirect(url)