onlines.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. from datetime import timedelta
  2. from django.core.cache import cache
  3. from django.utils import timezone
  4. from misago.models import Session
  5. class MembersOnline(object):
  6. def __init__(self, monitor, frequency=180):
  7. self.monitor = monitor
  8. self.frequency = frequency
  9. self._members = int(monitor['online_members'])
  10. self._all = int(monitor['online_all'])
  11. self._om = self._members
  12. self._oa = self._all
  13. if (monitor.expired('online_all', frequency) or
  14. monitor.expired('online_members', frequency)):
  15. self.count_sessions()
  16. def count_sessions(self):
  17. queryset = Session.objects.filter(matched=True).filter(crawler__isnull=True).filter(last__gte=timezone.now() - timedelta(seconds=self.frequency))
  18. self._all = queryset.count()
  19. self._members = queryset.filter(user__isnull=False).count()
  20. cache.delete_many(['team_users_online', 'ranks_online'])
  21. def new_session(self):
  22. self._all += 1
  23. def sign_in(self):
  24. self._members += 1
  25. def sign_out(self):
  26. if self._members:
  27. self._members -= 1
  28. @property
  29. def all(self):
  30. return self._all
  31. @property
  32. def members(self):
  33. return self._members
  34. def sync(self):
  35. if self._members != self._om:
  36. self.monitor['online_members'] = self._members
  37. if self._all != self._oa:
  38. self.monitor['online_all'] = self._all
  39. def stats(self, request=None):
  40. # Are we request-aware?
  41. if not request:
  42. return {
  43. 'members': self.members,
  44. 'all': self.all,
  45. }
  46. online = self.stats()
  47. # Here we check for signs that online stats are out of sync
  48. try:
  49. if not online['members'] and request.user.is_authenticated():
  50. raise ValueError()
  51. if online['members'] > online['all']:
  52. raise ValueError()
  53. if (online['members'] == online['all'] and
  54. not request.user.is_authenticated()):
  55. raise ValueError()
  56. return online
  57. except ValueError:
  58. if request.session.matched:
  59. self.count_sessions()
  60. return self.stats()
  61. else:
  62. if request.user.is_authenticated() and not online['members']:
  63. online['members'] += 1
  64. if online['members'] > online['all']:
  65. online['all'] = online['members']
  66. if request.user.is_anonymous() and online['members'] == online['all']:
  67. online['all'] += 1
  68. return online