comparison gpp/forums/views/subscriptions.py @ 386:9fcd366f22dc

Revert r323. Send out forum topic subscription emails as people post. Don't limit them.
author Brian Neal <bgneal@gmail.com>
date Thu, 17 Mar 2011 01:20:23 +0000
parents b2b37cdd020a
children 9d3bd7304050
comparison
equal deleted inserted replaced
385:2a03c69792d8 386:9fcd366f22dc
1 """This module handles the subscriptions of users to forum topics.""" 1 """This module handles the subscriptions of users to forum topics."""
2 import datetime
3
4 from django.conf import settings 2 from django.conf import settings
5 from django.contrib.auth.decorators import login_required 3 from django.contrib.auth.decorators import login_required
6 from django.contrib.sites.models import Site 4 from django.contrib.sites.models import Site
7 from django.core.paginator import InvalidPage 5 from django.core.paginator import InvalidPage
8 from django.core.urlresolvers import reverse 6 from django.core.urlresolvers import reverse
12 from django.shortcuts import get_object_or_404 10 from django.shortcuts import get_object_or_404
13 from django.shortcuts import render_to_response 11 from django.shortcuts import render_to_response
14 from django.template import RequestContext 12 from django.template import RequestContext
15 from django.views.decorators.http import require_POST 13 from django.views.decorators.http import require_POST
16 14
17 from forums.models import Topic, TopicLastVisit, Subscription 15 from forums.models import Topic
18 from core.functions import send_mail 16 from core.functions import send_mail
19 from core.paginator import DiggPaginator 17 from core.paginator import DiggPaginator
20
21
22 # This constant is the minimum amount of time a user will be
23 # notified of new posts in a topic. Currently it is set to 1 day.
24 # Thus a user will be notified at most once per day of new posts.
25 TOPIC_NOTIFY_DELAY = datetime.timedelta(days=1)
26 18
27 19
28 def notify_topic_subscribers(post): 20 def notify_topic_subscribers(post):
29 """ 21 """
30 The argument post is a newly created post. Send out an email 22 The argument post is a newly created post. Send out an email
31 notification to all subscribers of the post's parent Topic. 23 notification to all subscribers of the post's parent Topic.
32 The emails are throttled such that unless the user visits the topic,
33 only 1 email will be sent per TOPIC_NOTIFY_DELAY period.
34 Visiting the topic will reset this delay.
35
36 """ 24 """
37 #TODO: consider moving this function of the HTTP request/response cycle. 25 #TODO: consider moving this function of the HTTP request/response cycle.
38 26
39 topic = post.topic 27 topic = post.topic
40 subscriptions = Subscription.objects.filter(topic=post.topic).exclude( 28 recipients = topic.subscribers.exclude(id=post.user.id).values_list(
41 user=post.user).select_related() 29 'email', flat=True)
42
43 if not subscriptions:
44 return
45
46 subscriber_ids = [sub.user.id for sub in subscriptions]
47 tlvs = dict(TopicLastVisit.objects.filter(topic=topic,
48 user__in=subscriber_ids).values_list('user', 'last_visit'))
49
50 recipients = []
51 for sub in subscriptions:
52 if (sub.notify_date is None or
53 post.creation_date - sub.notify_date > TOPIC_NOTIFY_DELAY or
54 tlvs.get(sub.user.id, datetime.datetime.min) > sub.notify_date):
55
56 recipients.append(sub.user.email)
57 sub.notify_date = post.creation_date
58 sub.save()
59 30
60 if recipients: 31 if recipients:
61 site = Site.objects.get_current() 32 site = Site.objects.get_current()
62 subject = "[%s] Topic Reply: %s" % (site.name, topic.name) 33 subject = "[%s] Topic Reply: %s" % (site.name, topic.name)
63 url_prefix = "http://%s" % site.domain 34 url_prefix = "http://%s" % site.domain
78 @require_POST 49 @require_POST
79 def subscribe_topic(request, topic_id): 50 def subscribe_topic(request, topic_id):
80 """Subscribe the user to the requested topic.""" 51 """Subscribe the user to the requested topic."""
81 topic = get_object_or_404(Topic.objects.select_related(), id=topic_id) 52 topic = get_object_or_404(Topic.objects.select_related(), id=topic_id)
82 if topic.forum.category.can_access(request.user): 53 if topic.forum.category.can_access(request.user):
83 sub = Subscription(topic=topic, user=request.user) 54 topic.subscribers.add(request.user)
84 sub.save()
85 return HttpResponseRedirect( 55 return HttpResponseRedirect(
86 reverse("forums-subscription_status", args=[topic.id])) 56 reverse("forums-subscription_status", args=[topic.id]))
87 raise Http404 # TODO return HttpResponseForbidden instead 57 raise Http404
88 58
89 59
90 @login_required 60 @login_required
91 @require_POST 61 @require_POST
92 def unsubscribe_topic(request, topic_id): 62 def unsubscribe_topic(request, topic_id):
93 """Unsubscribe the user to the requested topic.""" 63 """Unsubscribe the user to the requested topic."""
94 topic = get_object_or_404(Topic, id=topic_id) 64 topic = get_object_or_404(Topic, id=topic_id)
95 try: 65 topic.subscribers.remove(request.user)
96 sub = Subscription.objects.get(topic=topic, user=request.user)
97 except Subscription.DoesNotExist:
98 pass
99 else:
100 sub.delete()
101 return HttpResponseRedirect( 66 return HttpResponseRedirect(
102 reverse("forums-subscription_status", args=[topic.id])) 67 reverse("forums-subscription_status", args=[topic.id]))
103 68
104 69
105 @login_required 70 @login_required
119 """Display a user's topic subscriptions, and allow them to be deleted.""" 84 """Display a user's topic subscriptions, and allow them to be deleted."""
120 85
121 user = request.user 86 user = request.user
122 if request.method == "POST": 87 if request.method == "POST":
123 if request.POST.get('delete_all'): 88 if request.POST.get('delete_all'):
124 Subscription.objects.filter(user=user).delete() 89 user.subscriptions.clear()
125 else: 90 else:
126 delete_ids = request.POST.getlist('delete_ids') 91 delete_ids = request.POST.getlist('delete_ids')
127 try: 92 try:
128 delete_ids = [int(id) for id in delete_ids] 93 delete_ids = [int(id) for id in delete_ids]
129 except ValueError: 94 except ValueError:
130 raise Http404 95 raise Http404
131 96
132 Subscription.objects.filter(user=user, topic__in=delete_ids).delete() 97 for topic in user.subscriptions.filter(id__in=delete_ids):
98 user.subscriptions.remove(topic)
133 99
134 return HttpResponseRedirect(reverse("forums-manage_subscriptions")) 100 return HttpResponseRedirect(reverse("forums-manage_subscriptions"))
135 101
136 page_num = request.GET.get('page', 1) 102 page_num = request.GET.get('page', 1)
137 topics = user.subscriptions.select_related().order_by('-update_date') 103 topics = user.subscriptions.select_related().order_by('-update_date')