Просмотр исходного кода

#445: fetch forums cutoffs for threads list

Rafał Pitoń 10 лет назад
Родитель
Сommit
ac3a0fa773

+ 5 - 2
misago/readtracker/dates.py

@@ -4,8 +4,11 @@ from django.conf import settings
 from django.utils import timezone
 from django.utils import timezone
 
 
 
 
-def is_date_tracked(user, date):
+def is_date_tracked(date, user, forum_read_cutoff=None):
     if date:
     if date:
-        return date > user.reads_cutoff
+        if forum_read_cutoff and forum_read_cutoff > date:
+            return False
+        else:
+            return date > user.reads_cutoff
     else:
     else:
         return False
         return False

+ 1 - 1
misago/readtracker/forumstracker.py

@@ -17,7 +17,7 @@ def make_read_aware(user, forums):
 
 
     forums_dict = {}
     forums_dict = {}
     for forum in forums:
     for forum in forums:
-        forum.is_read = not is_date_tracked(user, forum.last_post_on)
+        forum.is_read = not is_date_tracked(forum.last_post_on, user)
         forums_dict[forum.pk] = forum
         forums_dict[forum.pk] = forum
 
 
     for record in user.forumread_set.filter(forum__in=forums_dict.keys()):
     for record in user.forumread_set.filter(forum__in=forums_dict.keys()):

+ 14 - 3
misago/readtracker/tests/test_dates.py

@@ -14,10 +14,21 @@ class MockUser(object):
 class ReadTrackerDatesTests(TestCase):
 class ReadTrackerDatesTests(TestCase):
     def test_is_date_tracked(self):
     def test_is_date_tracked(self):
         """is_date_tracked validates dates"""
         """is_date_tracked validates dates"""
-        self.assertFalse(is_date_tracked(MockUser(), None))
+        self.assertFalse(is_date_tracked(None, MockUser()))
 
 
         past_date = timezone.now() - timedelta(minutes=10)
         past_date = timezone.now() - timedelta(minutes=10)
-        self.assertFalse(is_date_tracked(MockUser(), past_date))
+        self.assertFalse(is_date_tracked(past_date, MockUser()))
 
 
         future_date = timezone.now() + timedelta(minutes=10)
         future_date = timezone.now() + timedelta(minutes=10)
-        self.assertTrue(is_date_tracked(MockUser(), future_date))
+        self.assertTrue(is_date_tracked(future_date, MockUser()))
+
+    def test_is_date_tracked_with_forum_cutoff(self):
+        """is_date_tracked validates dates using forum cutoff"""
+        self.assertFalse(is_date_tracked(None, MockUser()))
+        past_date = timezone.now() + timedelta(minutes=10)
+
+        forum_cutoff = timezone.now() + timedelta(minutes=20)
+        self.assertFalse(is_date_tracked(past_date, MockUser(), forum_cutoff))
+
+        forum_cutoff = timezone.now() - timedelta(minutes=20)
+        self.assertTrue(is_date_tracked(past_date, MockUser(), forum_cutoff))

+ 20 - 4
misago/readtracker/threadstracker.py

@@ -13,15 +13,19 @@ def make_read_aware(user, target):
 
 
 
 
 def make_threads_read_aware(user, threads):
 def make_threads_read_aware(user, threads):
+    if not threads:
+        return None
+
     if user.is_anonymous():
     if user.is_anonymous():
         make_read(threads)
         make_read(threads)
         return None
         return None
 
 
-
+    forums_cutoffs = fetch_forums_cutoffs_for_threads(user, threads)
 
 
     threads_dict = {}
     threads_dict = {}
     for thread in threads:
     for thread in threads:
-        thread.is_read = not is_date_tracked(user, thread.last_post_on)
+        thread.is_read = not is_date_tracked(
+            thread.last_post_on, user, forums_cutoffs.get(thread.forum_id))
         thread.is_new = True
         thread.is_new = True
         if thread.is_read:
         if thread.is_read:
             thread.unread_replies = 0
             thread.unread_replies = 0
@@ -48,9 +52,21 @@ def make_read(threads):
         thread.is_read = True
         thread.is_read = True
 
 
 
 
+def fetch_forums_cutoffs_for_threads(users, threads):
+    forums = []
+    for thread in threads:
+        if thread.forum_id not in forums:
+            forums.append(thread.forum_id)
+
+    forums_dict = {}
+    for record in user.forumread_set.filter(forum__in=forums):
+        forums_dict[record.forum_id] = record.forum.last_read_on
+    return forums_dict
+
+
 def make_thread_read_aware(user, thread):
 def make_thread_read_aware(user, thread):
     thread.is_read = True
     thread.is_read = True
-    if user.is_authenticated() and is_date_tracked(user, thread.last_post_on):
+    if user.is_authenticated() and is_date_tracked(thread.last_post_on, user):
         try:
         try:
             record = user.threadread_set.filter(thread=thread).all()[0]
             record = user.threadread_set.filter(thread=thread).all()[0]
             thread.last_read_on = record.last_read_on
             thread.last_read_on = record.last_read_on
@@ -76,7 +92,7 @@ def make_posts_read_aware(user, thread, posts):
             post.is_read = True
             post.is_read = True
     else:
     else:
         for post in posts:
         for post in posts:
-            if is_date_tracked(user, post.updated_on):
+            if is_date_tracked(post.updated_on, user):
                 post.is_read = post.updated_on <= thread.last_read_on
                 post.is_read = post.updated_on <= thread.last_read_on
             else:
             else:
                 post.is_read = True
                 post.is_read = True