# HG changeset patch # User Brian Neal # Date 1261447685 0 # Node ID 2eb3984ccb15e8ec481444788d1c3490e433d6d7 # Parent 416353def4ca2d0030d362c28a39e339d153f708 Implement #45, add a who's online feature for the forums. Created middleware that caches usernames and guest session ids in the cache. Added a tag that displays this info. diff -r 416353def4ca -r 2eb3984ccb15 gpp/forums/middleware.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/forums/middleware.py Tue Dec 22 02:08:05 2009 +0000 @@ -0,0 +1,51 @@ +""" +Middleware for the forums application. +""" +import datetime + +from django.core.cache import cache +from django.conf import settings + + +USER_ONLINE_TIMEOUT = datetime.timedelta(minutes=15) +USERS_ONLINE_KEY = 'users_online' +GUESTS_ONLINE_KEY = 'guests_online' +USERS_CACHE_TIMEOUT = 60 * 60 * 24 # units are seconds + + +class WhosOnline(object): + """ + This middleware class keeps track of which registered users have + been seen recently, and the number of unique unregistered users. + We use the Django cache system to store this information. + This middleware should come after the authentication middleware, + as we count on the user attribute being attached to the request. + """ + + def process_request(self, request): + """ + Keep track of who is online. + """ + now = datetime.datetime.now() + cutoff = now - USER_ONLINE_TIMEOUT + users_online = cache.get(USERS_ONLINE_KEY, {}) + guests_online = cache.get(GUESTS_ONLINE_KEY, {}) + + # update timestamp for user + if request.user.is_authenticated(): + users_online[request.user.username] = now + else: + sid = request.COOKIES.get(settings.SESSION_COOKIE_NAME, '') + guests_online[sid] = now + + # expire old records + for username, timestamp in users_online.items(): + if timestamp < cutoff: + del users_online[username] + + for sid, timestamp in guests_online.items(): + if timestamp < cutoff: + del guests_online[sid] + + cache.set(USERS_ONLINE_KEY, users_online, USERS_CACHE_TIMEOUT) + cache.set(GUESTS_ONLINE_KEY, guests_online, USERS_CACHE_TIMEOUT) diff -r 416353def4ca -r 2eb3984ccb15 gpp/forums/templatetags/forum_tags.py --- a/gpp/forums/templatetags/forum_tags.py Sun Dec 20 20:42:19 2009 +0000 +++ b/gpp/forums/templatetags/forum_tags.py Tue Dec 22 02:08:05 2009 +0000 @@ -6,6 +6,7 @@ from pytz import timezone from django import template from django.conf import settings +from django.core.cache import cache from forums.models import Topic @@ -122,3 +123,23 @@ 'topics': topics, 'user': context['user'], } + + +@register.inclusion_tag('forums/whos_online_tag.html') +def whos_online(): + """ + Displays a list of who is online. + """ + users_online = cache.get('users_online', {}) + guests_online = cache.get('guests_online', {}) + num_users = len(users_online) + num_guests = len(guests_online) + total = num_users + num_guests + users = sorted(users_online.keys()) + + return { + 'num_users': num_users, + 'num_guests': num_guests, + 'total': total, + 'users': users, + } diff -r 416353def4ca -r 2eb3984ccb15 gpp/settings.py --- a/gpp/settings.py Sun Dec 20 20:42:19 2009 +0000 +++ b/gpp/settings.py Tue Dec 22 02:08:05 2009 +0000 @@ -75,6 +75,7 @@ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', + 'gpp.forums.middleware.WhosOnline', ) ROOT_URLCONF = 'gpp.urls' diff -r 416353def4ca -r 2eb3984ccb15 gpp/templates/forums/index.html --- a/gpp/templates/forums/index.html Sun Dec 20 20:42:19 2009 +0000 +++ b/gpp/templates/forums/index.html Tue Dec 22 02:08:05 2009 +0000 @@ -33,6 +33,7 @@ {% endfor %} +{% whos_online %}

{% current_forum_time user %}

{% endblock %} diff -r 416353def4ca -r 2eb3984ccb15 media/css/base.css --- a/media/css/base.css Sun Dec 20 20:42:19 2009 +0000 +++ b/media/css/base.css Tue Dec 22 02:08:05 2009 +0000 @@ -266,3 +266,7 @@ table.grid th,td { border: 1px solid #eee; } +ul.inline-list li { + display: inline; + margin: 0 3px; +}