Mercurial > public > sg101
view forums/unread.py @ 693:ad69236e8501
For issue #52, update many 3rd party Javascript libraries.
Updated to jquery 1.10.2, jquery ui 1.10.3.
This broke a lot of stuff.
- Found a newer version of the jquery cycle all plugin (3.0.3).
- Updated JPlayer to 2.4.0.
- Updated to MarkItUp 1.1.14. This also required me to add multiline attributes
set to true on various buttons in the markdown set.
- As per a stackoverflow post, added some code to get multiline titles in
a jQuery UI dialog. They removed that functionality but allow you to put it
back.
Tweaked the MarkItUp preview CSS to show blockquotes in italic.
Did not update TinyMCE at this time. I'm not using the JQuery version and this
version appears to work ok for now.
What I should do is make a repo for MarkItUp and do a vendor branch thing so
I don't have to futz around diffing directories to figure out if I'll lose
changes when I update.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Wed, 04 Sep 2013 19:55:20 -0500 |
parents | ee87ea74d46b |
children |
line wrap: on
line source
""" 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 import logging from django.db import IntegrityError from forums.models import ForumLastVisit, TopicLastVisit, Topic, Forum THRESHOLD = datetime.timedelta(days=14) ####################################################################### 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 # There is a race condition and sometimes another thread # saves a record before we do; just log this if it happens. try: flv.save() except IntegrityError: logging.exception('get_forum_unread_status') 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(forum=forum, update_date__gt=flv.begin_date) tracked_topics = TopicLastVisit.objects.filter( user=user, topic__forum=forum, last_visit__gt=flv.begin_date).select_related('topic') # 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.topic.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 break else: forum.has_unread = True break else: # If we made it through the above loop without breaking out, # then we are all caught up. forum.catchup(user, flv) forum.has_unread = False ####################################################################### def get_topic_unread_status(forum, topics, user): # Edge case: no topics if forum.last_post is None: return # This service isn't provided to unauthenticated users if not user.is_authenticated(): for topic in topics: topic.has_unread = False return now = datetime.datetime.now() # Get the ForumLastVisit record try: flv = ForumLastVisit.objects.get(forum=forum, user=user) except ForumLastVisit.DoesNotExist: # 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 # There is a race condition and sometimes another thread # saves a record before we do; just log this if it happens. try: flv.save() except IntegrityError: logging.exception('get_topic_unread_status') for topic in topics: topic.has_unread = False return # Are all the posts before our window? If so, all have been read. if forum.last_post.creation_date < flv.begin_date: for topic in topics: topic.has_unread = False return topic_ids = [topic.id for topic in topics] tlvs = TopicLastVisit.objects.filter(user=user, topic__id__in=topic_ids) tlvs = dict([(tlv.topic.id, tlv) for tlv in tlvs]) # Otherwise we have to go through the topics one by one: for topic in topics: if topic.update_date < flv.begin_date: topic.has_unread = False elif topic.update_date > flv.end_date: topic.has_unread = True elif topic.id in tlvs: topic.has_unread = topic.update_date > tlvs[topic.id].last_visit else: topic.has_unread = True ####################################################################### def get_post_unread_status(topic, posts, user): # This service isn't provided to unauthenticated users if not user.is_authenticated(): for post in posts: post.unread = False return # Get the ForumLastVisit record try: flv = ForumLastVisit.objects.get(forum=topic.forum, user=user) except ForumLastVisit.DoesNotExist: # One doesn't exist, all posts are old. for post in posts: post.unread = False return # Are all the posts before our window? If so, all have been read. if topic.last_post.creation_date < flv.begin_date: for post in posts: post.unread = False return # Do we have a topic last visit record for this topic? try: tlv = TopicLastVisit.objects.get(user=user, topic=topic) except TopicLastVisit.DoesNotExist: # No we don't, we could be all caught up, or all are new for post in posts: post.unread = post.creation_date > flv.end_date else: for post in posts: post.unread = post.creation_date > tlv.last_visit ####################################################################### def get_unread_topics(user): """Returns a list of topics the user hasn't read yet.""" # This is only available to authenticated users if not user.is_authenticated(): return [] now = datetime.datetime.now() # Obtain list of forums the user can view forums = Forum.objects.forums_for_user(user) # Get forum last visit records for the forum ids flvs = ForumLastVisit.objects.filter(user=user, forum__in=forums).select_related() flvs = dict([(flv.forum.id, flv) for flv in flvs]) unread_topics = [] topics = Topic.objects.none() for forum in forums: # if the user hasn't visited the forum, create a last # visit record set to "now" if not forum.id in flvs: flv = ForumLastVisit(user=user, forum=forum, begin_date=now, end_date=now) flv.save() else: flv = flvs[forum.id] topics |= Topic.objects.filter(forum=forum, update_date__gt=flv.begin_date).order_by('-update_date').select_related( 'forum', 'user', 'last_post', 'last_post__user') if topics is not None: # get all topic last visit records for the topics of interest tlvs = TopicLastVisit.objects.filter(user=user, topic__in=topics) tlvs = dict([(tlv.topic.id, tlv) for tlv in tlvs]) for topic in topics: if topic.id in tlvs: tlv = tlvs[topic.id] if topic.update_date > tlv.last_visit: unread_topics.append(topic) else: unread_topics.append(topic) return unread_topics