bgneal@160: """
bgneal@160: Middleware for the forums application.
bgneal@160: """
bgneal@160: import datetime
bgneal@160: 
bgneal@160: from django.core.cache import cache
bgneal@160: from django.conf import settings
bgneal@160: 
bgneal@160: 
bgneal@160: USER_ONLINE_TIMEOUT = datetime.timedelta(minutes=15)
bgneal@160: USERS_ONLINE_KEY = 'users_online'
bgneal@160: GUESTS_ONLINE_KEY = 'guests_online'
bgneal@160: USERS_CACHE_TIMEOUT = 60 * 60 * 24      # units are seconds
bgneal@160: 
bgneal@160: 
bgneal@160: class WhosOnline(object):
bgneal@160:     """
bgneal@160:     This middleware class keeps track of which registered users have
bgneal@160:     been seen recently, and the number of unique unregistered users.
bgneal@160:     We use the Django cache system to store this information.
bgneal@160:     This middleware should come after the authentication middleware,
bgneal@160:     as we count on the user attribute being attached to the request.
bgneal@160:     """
bgneal@160: 
bgneal@160:     def process_request(self, request):
bgneal@160:         """
bgneal@160:         Keep track of who is online.
bgneal@160:         """
bgneal@160:         now = datetime.datetime.now()
bgneal@160:         cutoff = now - USER_ONLINE_TIMEOUT
bgneal@160:         users_online = cache.get(USERS_ONLINE_KEY, {})
bgneal@160:         guests_online = cache.get(GUESTS_ONLINE_KEY, {})
bgneal@160: 
bgneal@160:         # update timestamp for user
bgneal@160:         if request.user.is_authenticated():
bgneal@160:             users_online[request.user.username] = now
bgneal@160:         else:
bgneal@160:             sid = request.COOKIES.get(settings.SESSION_COOKIE_NAME, '')
bgneal@160:             guests_online[sid] = now
bgneal@160: 
bgneal@160:         # expire old records
bgneal@160:         for username, timestamp in users_online.items():
bgneal@160:             if timestamp < cutoff:
bgneal@160:                 del users_online[username]
bgneal@160: 
bgneal@160:         for sid, timestamp in guests_online.items():
bgneal@160:             if timestamp < cutoff:
bgneal@160:                 del guests_online[sid]
bgneal@160: 
bgneal@160:         cache.set(USERS_ONLINE_KEY, users_online, USERS_CACHE_TIMEOUT)
bgneal@160:         cache.set(GUESTS_ONLINE_KEY, guests_online, USERS_CACHE_TIMEOUT)