Mercurial > public > sg101
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/forums/unread.py Sun Oct 11 19:10:54 2009 +0000 @@ -0,0 +1,99 @@ +""" +This file contains routines for implementing the "has unread" feature. +Forums, topics, and posts are displayed with a visual indication if they have +been read or not. +""" +import datetime + +from forums.models import ForumLastVisit, TopicLastVisit, Topic + + +THRESHOLD = datetime.timedelta(days=7) + + +def get_forum_unread_status(qs, user): + if not user.is_authenticated(): + for forum in qs: + forum.has_unread = False + return + + now = datetime.datetime.now() + min_date = now - THRESHOLD + + # retrieve ForumLastVisit records in one SQL query + forum_ids = [forum.id for forum in qs] + flvs = ForumLastVisit.objects.filter(user=user, + forum__in=forum_ids).select_related() + flvs = dict([(flv.forum.id, flv) for flv in flvs]) + + for forum in qs: + # Edge case: forum has no posts + if forum.last_post is None: + forum.has_unread = False + continue + + # Get the ForumLastVisit record + if forum.id in flvs: + flv = flvs[forum.id] + else: + # One doesn't exist, create a default one for next time, + # mark it as having no unread topics, and bail. + flv = ForumLastVisit(user=user, forum=forum) + flv.begin_date = now + flv.end_date = now + flv.save() + forum.has_unread = False + continue + + # If the last visit record was too far in the past, + # catch that user up and mark as no unreads. + if now - flv.end_date > THRESHOLD: + forum.catchup(user, flv) + forum.has_unread = False + continue + + # Check the easy cases first. Check the last_post in the + # forum. If created after the end_date in our window, there + # are new posts. Likewise, if before the begin_date in our window, + # there are no new posts. + if forum.last_post.creation_date > flv.end_date: + forum.has_unread = True + elif forum.last_post.creation_date < flv.begin_date: + if not flv.is_caught_up(): + forum.catchup(user, flv) + forum.has_unread = False + else: + # Going to have to examine the topics in our window. + # First adjust our window if it is too old. + if now - flv.begin_date > THRESHOLD: + flv.begin_date = min_date + flv.save() + TopicLastVisit.objects.filter(user=user, topic__forum=forum, + last_visit__lt=min_date).delete() + + topics = Topic.objects.filter(creation_date__gt=flv.begin_date) + tracked_topics = TopicLastVisit.objects.filter(user=user, + topic__forum=forum, last_visit__gt=flv.begin_date) + + # If the number of topics created since our window was started + # is greater than the tracked topic records, then there are new + # posts. + if topics.count() > tracked_topics.count(): + forum.has_unread = True + continue + + tracked_dict = dict([(t.id, t) for t in tracked_topics]) + + for topic in topics: + if topic.id in tracked_dict: + if topic.update_date > tracked_dict[topic.id].last_visit: + forum.has_unread = True + continue + else: + forum.has_unread = True + continue + + # If we made it through the above loop without continuing, then + # we are all caught up. + forum.catchup(user, flv) + forum.has_unread = False