bgneal@232: """This module handles the subscriptions of users to forum topics."""
bgneal@232: from django.conf import settings
bgneal@232: from django.contrib.auth.decorators import login_required
bgneal@232: from django.contrib.sites.models import Site
bgneal@232: from django.core.paginator import InvalidPage
bgneal@232: from django.core.urlresolvers import reverse
bgneal@232: from django.http import HttpResponseRedirect
bgneal@232: from django.http import Http404
bgneal@232: from django.template.loader import render_to_string
bgneal@232: from django.shortcuts import get_object_or_404
bgneal@232: from django.shortcuts import render_to_response
bgneal@232: from django.template import RequestContext
bgneal@232: from django.views.decorators.http import require_POST
bgneal@232: 
bgneal@386: from forums.models import Topic
bgneal@459: import forums.permissions as perms
bgneal@232: from core.functions import send_mail
bgneal@232: from core.paginator import DiggPaginator
bgneal@232: 
bgneal@232: 
bgneal@522: def notify_topic_subscribers(post, defer=True):
bgneal@301:     """
bgneal@301:     The argument post is a newly created post. Send out an email
bgneal@301:     notification to all subscribers of the post's parent Topic.
bgneal@522: 
bgneal@522:     The defer flag is passed to core.functions.send_mail. If True, the mail is
bgneal@522:     sent on a Celery task. If False, the mail is sent on the caller's thread.
bgneal@301:     """
bgneal@232:     topic = post.topic
bgneal@386:     recipients = topic.subscribers.exclude(id=post.user.id).values_list(
bgneal@386:             'email', flat=True)
bgneal@232: 
bgneal@232:     if recipients:
bgneal@232:         site = Site.objects.get_current()
bgneal@232:         subject = "[%s] Topic Reply: %s" % (site.name, topic.name)
bgneal@232:         url_prefix = "http://%s" % site.domain
bgneal@232:         post_url = url_prefix + post.get_absolute_url()
bgneal@232:         unsubscribe_url = url_prefix + reverse("forums-manage_subscriptions")
bgneal@232:         msg = render_to_string("forums/topic_notify_email.txt", {
bgneal@232:                 'poster': post.user.username,
bgneal@232:                 'topic_name': topic.name,
bgneal@232:                 'message': post.body,
bgneal@232:                 'post_url': post_url,
bgneal@232:                 'unsubscribe_url': unsubscribe_url,
bgneal@232:                 })
bgneal@232:         for recipient in recipients:
bgneal@522:             send_mail(subject, msg, settings.DEFAULT_FROM_EMAIL, [recipient],
bgneal@522:                     defer=defer)
bgneal@232: 
bgneal@232: 
bgneal@232: @login_required
bgneal@232: @require_POST
bgneal@232: def subscribe_topic(request, topic_id):
bgneal@232:     """Subscribe the user to the requested topic."""
bgneal@232:     topic = get_object_or_404(Topic.objects.select_related(), id=topic_id)
bgneal@459:     if perms.can_access(topic.forum.category, request.user):
bgneal@386:         topic.subscribers.add(request.user)
bgneal@232:         return HttpResponseRedirect(
bgneal@232:             reverse("forums-subscription_status", args=[topic.id]))
bgneal@386:     raise Http404
bgneal@232: 
bgneal@232: 
bgneal@232: @login_required
bgneal@232: @require_POST
bgneal@232: def unsubscribe_topic(request, topic_id):
bgneal@232:     """Unsubscribe the user to the requested topic."""
bgneal@232:     topic = get_object_or_404(Topic, id=topic_id)
bgneal@386:     topic.subscribers.remove(request.user)
bgneal@232:     return HttpResponseRedirect(
bgneal@232:         reverse("forums-subscription_status", args=[topic.id]))
bgneal@232: 
bgneal@232: 
bgneal@232: @login_required
bgneal@232: def subscription_status(request, topic_id):
bgneal@232:     """Display the subscription status for the given topic."""
bgneal@232:     topic = get_object_or_404(Topic.objects.select_related(), id=topic_id)
bgneal@232:     is_subscribed = request.user in topic.subscribers.all()
bgneal@232:     return render_to_response('forums/subscription_status.html', {
bgneal@232:         'topic': topic,
bgneal@232:         'is_subscribed': is_subscribed,
bgneal@232:         },
bgneal@232:         context_instance=RequestContext(request))
bgneal@232: 
bgneal@232: 
bgneal@232: @login_required
bgneal@232: def manage_subscriptions(request):
bgneal@232:     """Display a user's topic subscriptions, and allow them to be deleted."""
bgneal@232: 
bgneal@232:     user = request.user
bgneal@232:     if request.method == "POST":
bgneal@232:         if request.POST.get('delete_all'):
bgneal@386:             user.subscriptions.clear()
bgneal@232:         else:
bgneal@232:             delete_ids = request.POST.getlist('delete_ids')
bgneal@232:             try:
bgneal@232:                 delete_ids = [int(id) for id in delete_ids]
bgneal@232:             except ValueError:
bgneal@232:                 raise Http404
bgneal@232: 
bgneal@386:             for topic in user.subscriptions.filter(id__in=delete_ids):
bgneal@386:                 user.subscriptions.remove(topic)
bgneal@232: 
bgneal@383:         return HttpResponseRedirect(reverse("forums-manage_subscriptions"))
bgneal@383: 
bgneal@383:     page_num = request.GET.get('page', 1)
bgneal@232:     topics = user.subscriptions.select_related().order_by('-update_date')
bgneal@232:     paginator = DiggPaginator(topics, 20, body=5, tail=2, margin=3, padding=2)
bgneal@232:     try:
bgneal@232:         page_num = int(page_num)
bgneal@232:     except ValueError:
bgneal@232:         page_num = 1
bgneal@232:     try:
bgneal@232:         page = paginator.page(page_num)
bgneal@232:     except InvalidPage:
bgneal@232:         raise Http404
bgneal@232: 
bgneal@232:     return render_to_response('forums/manage_topics.html', {
bgneal@232:         'page_title': 'Topic Subscriptions',
bgneal@232:         'description': 'The forum topics you are currently subscribed to are listed below.',
bgneal@232:         'page': page,
bgneal@232:         },
bgneal@232:         context_instance=RequestContext(request))