trackers.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. from datetime import timedelta
  2. from django.conf import settings
  3. from django.utils import timezone
  4. from misago.readstracker.models import Record
  5. from misago.threads.models import Thread
  6. class ForumsTracker(object):
  7. def __init__(self, user):
  8. self.user = user
  9. self.cutoff = timezone.now() - timedelta(days=settings.READS_TRACKER_LENGTH)
  10. self.forums = {}
  11. if self.user.is_authenticated() and settings.READS_TRACKER_LENGTH > 0:
  12. for forum in Record.objects.filter(user=user).filter(updated__gte=self.cutoff).values('id', 'forum_id', 'updated', 'cleared'):
  13. self.forums[forum['forum_id']] = forum
  14. def is_read(self, forum):
  15. if not self.user.is_authenticated() or not forum.last_thread_date:
  16. return True
  17. try:
  18. return forum.last_thread_date <= self.cutoff or forum.last_thread_date <= self.forums[forum.pk]['cleared']
  19. except KeyError:
  20. return False
  21. class ThreadsTracker(object):
  22. def __init__(self, user, forum):
  23. self.need_sync = False
  24. self.need_update = False
  25. self.user = user
  26. self.forum = forum
  27. self.cutoff = timezone.now() - timedelta(days=settings.READS_TRACKER_LENGTH)
  28. if user.is_authenticated():
  29. try:
  30. self.record = Record.objects.get(user=user,forum=forum)
  31. if self.record.cleared > self.cutoff:
  32. self.cutoff = self.record.cleared
  33. except Record.DoesNotExist:
  34. self.record = Record(user=user,forum=forum,cleared=self.cutoff)
  35. self.threads = self.record.get_threads()
  36. def get_read_date(self, thread):
  37. if not self.user.is_authenticated():
  38. return timezone.now()
  39. try:
  40. if self.threads[thread.pk] > self.cutoff:
  41. return self.threads[thread.pk]
  42. except KeyError:
  43. pass
  44. return self.cutoff
  45. def is_read(self, thread):
  46. if not self.user.is_authenticated():
  47. return True
  48. try:
  49. if thread.last <= self.cutoff and thread.pk in self.threads:
  50. del self.threads[thread.pk]
  51. self.need_update = True
  52. return thread.last <= self.cutoff or thread.last <= self.threads[thread.pk]
  53. except KeyError:
  54. return False
  55. def set_read(self, thread, post):
  56. if self.user.is_authenticated():
  57. try:
  58. if self.threads[thread.pk] < post.date:
  59. self.threads[thread.pk] = post.date
  60. self.need_sync = True
  61. except KeyError:
  62. self.threads[thread.pk] = post.date
  63. self.need_sync = True
  64. def sync(self):
  65. now = timezone.now()
  66. if self.need_sync:
  67. unread_threads = 0
  68. for thread in Thread.objects.filter(last__gte=self.record.cleared).all():
  69. if not self.is_read(thread):
  70. unread_threads += 1
  71. if not unread_threads:
  72. self.record.cleared = now
  73. if self.need_sync or self.need_update:
  74. self.record.updated = now
  75. self.record.set_threads(self.threads)
  76. self.record.save(force_update=self.record.pk)