My favorites | Sign in
Project Home Wiki Issues Source
READ-ONLY: This project has been archived. For more information see this post.
Search
for
  Advanced search   Search tips   Subscriptions

Issue 63 attachment: unread-posts.patch (3.8 KB)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
diff --git a/models.py b/models.py
index f689f4c..e11716b 100644
--- a/models.py
+++ b/models.py
@@ -263,3 +263,11 @@ class Subscription(models.Model):

def __unicode__(self):
return u"%s to %s" % (self.author, self.thread)
+
+class ThreadTracker(models.Model):
+ """
+ Keep track of updated threads for each user.
+ """
+ user = models.ForeignKey(User)
+ thread = models.ForeignKey(Thread)
+ last_read = models.DateTimeField(_("Last Read"), blank=True, null=True)
diff --git a/templatetags/forum_tags.py b/templatetags/forum_tags.py
index 8c5bcb4..046b046 100644
--- a/templatetags/forum_tags.py
+++ b/templatetags/forum_tags.py
@@ -1,9 +1,13 @@
-from forum.models import Thread, Post
+from forum.models import Thread, Post, ThreadTracker
from django.utils.translation import ugettext as _
from django.template import Library, Node, TemplateSyntaxError, Variable, resolve_variable
+from django.conf import settings
+from datetime import datetime

register = Library()

+FORUM_EPOCH = getattr(settings, 'FORUM_EPOCH', datetime.now())
+
def forum_latest_thread_activity(parser, token):
"""
{% forum_latest_thread_activity [number] as [context_var] %}
@@ -79,6 +83,42 @@ class ForumLatestUserPostsNode(Node):
context[self.context_var] = Post.objects.select_related().filter(author=user).order_by('-time')[:self.number]
return ''

+def forum_thread_read(parser, token):
+ """
+ {% forum_thread_read <user> <thread> [as <context_var>] %}
+ """
+ bits = token.contents.split()
+ if len(bits) == 3:
+ context_var = 'thread_read'
+ elif len(bits) == 5:
+ if bits[3] != 'as':
+ raise TemplateSyntaxError("third argument to %s must be 'as'" % bits[0])
+ context_var = bits[4]
+ else:
+ raise TemplateSyntaxError('%s tag has incorrect number of arguments' % bits[0])
+ return ForumThreadReadNode(bits[1], bits[2], context_var)
+
+class ForumThreadReadNode(Node):
+ def __init__(self, user, thread, context_var):
+ self.user = Variable(user)
+ self.thread = Variable(thread)
+ self.context_var = context_var
+
+ def render(self, context):
+ user = self.user.resolve(context)
+ thread = self.thread.resolve(context)
+ if not thread.latest_post_time:
+ context[self.context_var] = False
+ return ''
+ context[self.context_var] = thread.latest_post_time > FORUM_EPOCH
+ try:
+ track = ThreadTracker.objects.select_related().get(user=user,thread=thread)
+ context[self.context_var] = track.last_read < thread.latest_post_time
+ except ThreadTracker.DoesNotExist:
+ pass
+ return ''
+
register.tag('forum_latest_posts', forum_latest_posts)
register.tag('forum_latest_thread_activity', forum_latest_thread_activity)
register.tag('forum_latest_user_posts', forum_latest_user_posts)
+register.tag('forum_thread_read', forum_thread_read)
diff --git a/views.py b/views.py
index 99408cf..9fd5edc 100644
--- a/views.py
+++ b/views.py
@@ -16,7 +16,7 @@ from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from django.views.generic.list_detail import object_list

-from forum.models import Forum,Thread,Post,Subscription
+from forum.models import Forum,Thread,Post,Subscription,ThreadTracker
from forum.forms import CreateThreadForm, ReplyForm

FORUM_PAGINATION = getattr(settings, 'FORUM_PAGINATION', 10)
@@ -66,6 +66,10 @@ def thread(request, thread):
s = None
if request.user.is_authenticated():
s = t.subscription_set.select_related().filter(author=request.user)
+ kwargs = {'user': request.user, 'thread': t}
+ track, created = ThreadTracker.objects.get_or_create(defaults=kwargs, **kwargs)
+ track.last_read = datetime.now()
+ track.save()

t.views += 1
t.save()
Powered by Google Project Hosting