changeset 160:2eb3984ccb15

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.
author Brian Neal <bgneal@gmail.com>
date Tue, 22 Dec 2009 02:08:05 +0000
parents 416353def4ca
children 445e1466a98d
files gpp/forums/middleware.py gpp/forums/templatetags/forum_tags.py gpp/settings.py gpp/templates/forums/index.html media/css/base.css
diffstat 5 files changed, 78 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /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)
--- 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,
+    }
--- 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'
--- 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 @@
       </tbody>
    </table>
 {% endfor %}
+{% whos_online %}
 <p>{% current_forum_time user %}</p>
 </div>
 {% endblock %}
--- 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;
+}