threadstracker.py 3.5 KB

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