threads.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. from misago.readtracker.dates import cutoff_date, is_date_tracked
  2. from misago.readtracker.forums import sync_forum_record
  3. __all__ = [
  4. 'make_threads_read_aware',
  5. 'make_threads_read',
  6. 'make_thread_read_aware',
  7. 'make_posts_read_aware',
  8. 'sync_thread_read',
  9. ]
  10. def make_threads_read_aware(user, threads):
  11. if user.is_anonymous():
  12. make_threads_read(threads)
  13. return None
  14. threads_dict = {}
  15. for thread in threads:
  16. thread.is_read = not is_date_tracked(thread.last_post_on)
  17. if thread.is_read:
  18. thread.unread_replies = 0
  19. else:
  20. thread.unread_replies = thread.replies
  21. threads_dict[thread.pk] = thread
  22. for record in user.threadread_set.filter(thread__in=threads_dict.keys()):
  23. if record.thread_id in threads_dict:
  24. thread = threads_dict[record.thread_id]
  25. thread.is_read = record.last_read_on >= thread.last_post_on
  26. if thread.is_read:
  27. thread.unread_replies = 0
  28. else:
  29. thread.unread_replies = thread.replies - record.read_replies
  30. def make_threads_read(threads):
  31. for thread in threads:
  32. thread.unread_replies = 0
  33. thread.is_read = True
  34. def make_thread_read_aware(user, thread):
  35. thread.is_read = True
  36. if user.is_authenticated() and is_date_tracked(thread.last_post_on):
  37. try:
  38. record = user.threadread_set.filter(thread=thread).all()[0]
  39. thread.last_read_on = record.last_read_on
  40. thread.is_read = thread.last_post_on <= record.last_read_on
  41. thread.read_record = record
  42. except IndexError:
  43. thread.read_record = None
  44. thread.is_read = False
  45. thread.last_read_on = cutoff_date()
  46. def make_posts_read_aware(thread, posts):
  47. try:
  48. is_thread_read = thread.is_read
  49. except AttributeError:
  50. raise ValueError("thread passed make_posts_read_aware should be "
  51. "read aware too via make_thread_read_aware")
  52. if is_thread_read:
  53. for post in posts:
  54. post.is_read = True
  55. else:
  56. for post in posts:
  57. if is_date_tracked(post.updated_on):
  58. post.is_read = post.updated_on <= thread.last_read_on
  59. else:
  60. post.is_read = True
  61. def count_read_replies(user, thread, last_read_reply):
  62. if last_read_reply.updated_on >= thread.last_read_on:
  63. return 0
  64. else:
  65. last_reply_date = last_read_reply.last_read_on
  66. queryset = thread.post_set.filter(last_read_on__lte=last_reply_date)
  67. queryset = queryset.filter(is_moderated=False)
  68. return queryset.count()
  69. def sync_thread_read(user, thread, last_read_reply):
  70. if not thread.is_read:
  71. if thread.last_read_on < last_read_reply.updated_on:
  72. read_thread(user, thread, last_read_reply)
  73. def read_thread(user, thread, last_read_reply):
  74. read_replies = count_read_replies(user, thread, last_read_reply)
  75. if thread.read_record:
  76. thread.read_record.read_replies = read_replies
  77. thread.read_record.last_read_on = last_read_reply.updated_on
  78. thread.read_record.save(update_fields=['read_replies', 'last_read_on'])
  79. else:
  80. user.threadread_set.create(
  81. forum=thread.forum,
  82. thread=thread,
  83. read_replies=read_replies,
  84. last_read_on=last_read_reply.updated_on)
  85. if last_read_reply.updated_on == thread.last_post_on:
  86. sync_forum_record(user, thread.forum)