1
from django.conf import settings
2
from django.core.cache import cache
3
from django.contrib.auth.models import User
4
from django.utils.deprecation import MiddlewareMixin
5
from django.contrib.auth import user_logged_out
6
from django.dispatch import receiver
8
ONLINE_THRESHOLD = getattr(settings, 'ONLINE_THRESHOLD', 60 * 15)
9
ONLINE_MAX = getattr(settings, 'ONLINE_MAX', 50)
12
def get_online_now(self):
13
return User.objects.filter(id__in=self.online_now_ids or [])
16
@receiver(user_logged_out)
17
def logout(sender, **kwargs):
19
cache.delete('online-%s' % kwargs['user'].id)
20
except AttributeError:
24
class OnlineNowMiddleware(MiddlewareMixin):
25
"""Maintains a list of users who have interacted with the website recently.
27
Their user IDs are available as ``online_now_ids`` on the request
28
object, and their corresponding users are available (lazily) as the
29
``online_now`` property on the request object.
33
def process_request(self, request):
35
uids = cache.get('online-now', [])
37
# Perform the multiget on the individual online uid keys
38
online_keys = ['online-%s' % (u,) for u in uids]
39
fresh = cache.get_many(online_keys).keys()
40
online_now_ids = [int(k.replace('online-', '')) for k in fresh]
42
# If the user is authenticated, add their id to the list
43
if request.user.is_authenticated:
45
# If their uid is already in the list, we want to bump it
46
# to the top, so we remove the earlier entry.
47
if uid in online_now_ids:
48
online_now_ids.remove(uid)
49
online_now_ids.append(uid)
50
if len(online_now_ids) > ONLINE_MAX:
53
# Attach our modifications to the request object
54
request.__class__.online_now_ids = online_now_ids
55
request.__class__.online_now = property(get_online_now)
58
cache.set('online-%s' % (request.user.pk,), True, ONLINE_THRESHOLD)
59
cache.set('online-now', online_now_ids, ONLINE_THRESHOLD)