Mercurial > public > sg101
comparison gpp/forums/unread.py @ 113:d97ceb95ce02
Forums: ForumLastVisit logic in place. Need to add code for topics and posts next.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sun, 11 Oct 2009 19:10:54 +0000 |
parents | |
children | 535d02d1c017 |
comparison
equal
deleted
inserted
replaced
112:d1b0b86441c0 | 113:d97ceb95ce02 |
---|---|
1 """ | |
2 This file contains routines for implementing the "has unread" feature. | |
3 Forums, topics, and posts are displayed with a visual indication if they have | |
4 been read or not. | |
5 """ | |
6 import datetime | |
7 | |
8 from forums.models import ForumLastVisit, TopicLastVisit, Topic | |
9 | |
10 | |
11 THRESHOLD = datetime.timedelta(days=7) | |
12 | |
13 | |
14 def get_forum_unread_status(qs, user): | |
15 if not user.is_authenticated(): | |
16 for forum in qs: | |
17 forum.has_unread = False | |
18 return | |
19 | |
20 now = datetime.datetime.now() | |
21 min_date = now - THRESHOLD | |
22 | |
23 # retrieve ForumLastVisit records in one SQL query | |
24 forum_ids = [forum.id for forum in qs] | |
25 flvs = ForumLastVisit.objects.filter(user=user, | |
26 forum__in=forum_ids).select_related() | |
27 flvs = dict([(flv.forum.id, flv) for flv in flvs]) | |
28 | |
29 for forum in qs: | |
30 # Edge case: forum has no posts | |
31 if forum.last_post is None: | |
32 forum.has_unread = False | |
33 continue | |
34 | |
35 # Get the ForumLastVisit record | |
36 if forum.id in flvs: | |
37 flv = flvs[forum.id] | |
38 else: | |
39 # One doesn't exist, create a default one for next time, | |
40 # mark it as having no unread topics, and bail. | |
41 flv = ForumLastVisit(user=user, forum=forum) | |
42 flv.begin_date = now | |
43 flv.end_date = now | |
44 flv.save() | |
45 forum.has_unread = False | |
46 continue | |
47 | |
48 # If the last visit record was too far in the past, | |
49 # catch that user up and mark as no unreads. | |
50 if now - flv.end_date > THRESHOLD: | |
51 forum.catchup(user, flv) | |
52 forum.has_unread = False | |
53 continue | |
54 | |
55 # Check the easy cases first. Check the last_post in the | |
56 # forum. If created after the end_date in our window, there | |
57 # are new posts. Likewise, if before the begin_date in our window, | |
58 # there are no new posts. | |
59 if forum.last_post.creation_date > flv.end_date: | |
60 forum.has_unread = True | |
61 elif forum.last_post.creation_date < flv.begin_date: | |
62 if not flv.is_caught_up(): | |
63 forum.catchup(user, flv) | |
64 forum.has_unread = False | |
65 else: | |
66 # Going to have to examine the topics in our window. | |
67 # First adjust our window if it is too old. | |
68 if now - flv.begin_date > THRESHOLD: | |
69 flv.begin_date = min_date | |
70 flv.save() | |
71 TopicLastVisit.objects.filter(user=user, topic__forum=forum, | |
72 last_visit__lt=min_date).delete() | |
73 | |
74 topics = Topic.objects.filter(creation_date__gt=flv.begin_date) | |
75 tracked_topics = TopicLastVisit.objects.filter(user=user, | |
76 topic__forum=forum, last_visit__gt=flv.begin_date) | |
77 | |
78 # If the number of topics created since our window was started | |
79 # is greater than the tracked topic records, then there are new | |
80 # posts. | |
81 if topics.count() > tracked_topics.count(): | |
82 forum.has_unread = True | |
83 continue | |
84 | |
85 tracked_dict = dict([(t.id, t) for t in tracked_topics]) | |
86 | |
87 for topic in topics: | |
88 if topic.id in tracked_dict: | |
89 if topic.update_date > tracked_dict[topic.id].last_visit: | |
90 forum.has_unread = True | |
91 continue | |
92 else: | |
93 forum.has_unread = True | |
94 continue | |
95 | |
96 # If we made it through the above loop without continuing, then | |
97 # we are all caught up. | |
98 forum.catchup(user, flv) | |
99 forum.has_unread = False |