Browse Source

Online tracker is now configurable #132

Ralfp 12 years ago
parent
commit
4f5d1fd14a

+ 6 - 7
misago/apps/index.py

@@ -18,6 +18,9 @@ def index(request):
                 popular_threads.append(thread)
                 popular_threads.append(thread)
             cache.set('thread_ranking_%s' % request.user.make_acl_key(), popular_threads, 60 * request.settings['thread_ranking_refresh'])
             cache.set('thread_ranking_%s' % request.user.make_acl_key(), popular_threads, 60 * request.settings['thread_ranking_refresh'])
 
 
+    # Users online
+    users_online = request.onlines.stats()
+
     # Ranks online
     # Ranks online
     ranks_list = cache.get('ranks_online', 'nada')
     ranks_list = cache.get('ranks_online', 'nada')
     if ranks_list == 'nada':
     if ranks_list == 'nada':
@@ -37,7 +40,7 @@ def index(request):
             ranks_list.append(rank_entry)
             ranks_list.append(rank_entry)
             ranks_dict[rank.pk] = rank_entry
             ranks_dict[rank.pk] = rank_entry
         if ranks_dict:
         if ranks_dict:
-            for session in Session.objects.select_related('user').filter(rank__in=ranks_dict.keys()).filter(last__gte=timezone.now() - timedelta(seconds=request.settings['sessions_tracker_sync_frequency'])).filter(user__isnull=False):
+            for session in Session.objects.select_related('user').filter(rank__in=ranks_dict.keys()).filter(last__gte=timezone.now() - timedelta(seconds=request.settings['online_counting_frequency'])).filter(user__isnull=False):
                 if not session.user_id in users_list:
                 if not session.user_id in users_list:
                     ranks_dict[session.user.rank_id]['online'].append(session.user)
                     ranks_dict[session.user.rank_id]['online'].append(session.user)
                     ranks_dict[session.user.rank_id]['pks'].append(session.user.pk)
                     ranks_dict[session.user.rank_id]['pks'].append(session.user.pk)
@@ -48,21 +51,17 @@ def index(request):
                     ranks_dict[request.user.rank_id]['online'].append(request.user)
                     ranks_dict[request.user.rank_id]['online'].append(request.user)
                     ranks_dict[request.user.rank_id]['pks'].append(request.user.pk)
                     ranks_dict[request.user.rank_id]['pks'].append(request.user.pk)
                     users_list.append(request.user.pk)
                     users_list.append(request.user.pk)
-            cache.set('team_users_online', users_list, request.settings['sessions_tracker_sync_frequency'])
+            cache.set('team_users_online', users_list, request.settings['online_counting_frequency'])
             del ranks_dict
             del ranks_dict
             del users_list
             del users_list
-        cache.set('ranks_online', ranks_list, request.settings['sessions_tracker_sync_frequency'])
+        cache.set('ranks_online', ranks_list, request.settings['online_counting_frequency'])
     elif request.user.is_authenticated():
     elif request.user.is_authenticated():
         for rank in ranks_list:
         for rank in ranks_list:
             if rank['id'] == request.user.rank_id and not request.user.pk in rank['pks']:
             if rank['id'] == request.user.rank_id and not request.user.pk in rank['pks']:
                 rank['online'].append(request.user)
                 rank['online'].append(request.user)
                 rank['pks'].append(request.user.pk)
                 rank['pks'].append(request.user.pk)
-                request.onlines.count_sessions()
                 break
                 break
 
 
-    # Users online
-    users_online = request.onlines.stats(request)
-
     # Load reads tracker and build forums list
     # Load reads tracker and build forums list
     reads_tracker = ForumsTracker(request.user)
     reads_tracker = ForumsTracker(request.user)
     forums_list = Forum.objects.treelist(request.acl.forums, tracker=reads_tracker)
     forums_list = Forum.objects.treelist(request.acl.forums, tracker=reads_tracker)

+ 8 - 1
misago/apps/signin/views.py

@@ -1,3 +1,4 @@
+from django.core.cache import cache
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 from django.template import RequestContext
 from django.template import RequestContext
@@ -106,5 +107,11 @@ def signout(request):
     request.messages.set_flash(Message(_("You have been signed out.")), 'info', 'security')
     request.messages.set_flash(Message(_("You have been signed out.")), 'info', 'security')
     if request.firewall.admin:
     if request.firewall.admin:
         return redirect(reverse(site.get_admin_index()))
         return redirect(reverse(site.get_admin_index()))
-    request.onlines.count_sessions()
+    else:
+        ranks_online = cache.get('ranks_online', 'nada')
+        if ranks_online != 'nada':
+            for rank in ranks_online:
+                if rank['id'] == user.rank_id:
+                    cache.delete('ranks_online')
+                    break
     return redirect(reverse('index'))
     return redirect(reverse('index'))

+ 17 - 8
misago/fixtures/signingsettings.py

@@ -15,14 +15,6 @@ settings_fixture = (
                 'name':         _("Check IP on session authorization"),
                 'name':         _("Check IP on session authorization"),
                 'description':  _("Makes sessions more secure, but can cause problems with proxies and VPN's."),
                 'description':  _("Makes sessions more secure, but can cause problems with proxies and VPN's."),
             }),
             }),
-            ('sessions_tracker_sync_frequency', {
-                'value':        300,
-                'type':         "integer",
-                'input':        "text",
-                'extra':         {'min': 15},
-                'name':         _("Online Tracker Updates Frequency"),
-                'description':  _("How often do you want online tracker to synchronize itself with database? Low numbers provide good accuracy at cost of database traffic while great number provides your users with general idea how many are currently online while at same time keeping stress off your database."),
-            }),
             ('remember_me_allow', {
             ('remember_me_allow', {
                 'value':        True,
                 'value':        True,
                 'type':         "boolean",
                 'type':         "boolean",
@@ -45,6 +37,23 @@ settings_fixture = (
                 'name':         _('Allow "Remember Me" tokens refreshing'),
                 'name':         _('Allow "Remember Me" tokens refreshing'),
                 'description':  _('Set this setting to off if you want to force your users to periodically update their "Remember Me" tokens by signing in. If this option is on, Tokens are updated when they are used to open new session.'),
                 'description':  _('Set this setting to off if you want to force your users to periodically update their "Remember Me" tokens by signing in. If this option is on, Tokens are updated when they are used to open new session.'),
             }),
             }),
+            ('online_counting', {
+                'value':        "real",
+                'type':         "string",
+                'input':        "choice",
+                'extra':        {'choices': [('no', _("Don't count users online")), ('snap', _("Periodically count and cache onlines")), ('real', _("Real time"))]},
+                'separator':    _("Online Counting"),
+                'name':         _("Count and display number of users online on board index."),
+                'description':  _("Online counter helps members tell how active other members are at the moment. Large forums should use periodical counting that saves resources but is not accurate while small ones can use real time counting that offers complete accuracy without putting much stress on sessions table."),
+            }),
+            ('online_counting_frequency', {
+                'value':        300,
+                'type':         "integer",
+                'input':        "text",
+                'extra':        {'min': 1},
+                'name':         _("Cache expiration"),
+                'description':  _('If you are using cache to count number of users online, here you can enter number of seconds after which cache is marked as expired and refreshed with new data.'),
+            }),
         ),
         ),
     }),
     }),
 )
 )

+ 1 - 1
misago/middleware/user.py

@@ -15,7 +15,7 @@ def set_timezone(new_tz):
 
 
 class UserMiddleware(object):
 class UserMiddleware(object):
     def process_request(self, request):
     def process_request(self, request):
-        request.onlines = MembersOnline(request.monitor, request.settings['sessions_tracker_sync_frequency'])
+        request.onlines = MembersOnline(request.settings['online_counting'], request.monitor, request.settings['online_counting_frequency'])
 
 
         if request.session.created() and not request.firewall.admin:
         if request.session.created() and not request.firewall.admin:
             request.onlines.new_session()
             request.onlines.new_session()

+ 14 - 40
misago/onlines.py

@@ -4,14 +4,15 @@ from django.utils import timezone
 from misago.models import Session
 from misago.models import Session
 
 
 class MembersOnline(object):
 class MembersOnline(object):
-    def __init__(self, monitor, frequency=180):
+    def __init__(self, mode, monitor, frequency=180):
         self.monitor = monitor
         self.monitor = monitor
         self.frequency = frequency
         self.frequency = frequency
+        self._mode = mode
         self._members = int(monitor['online_members'])
         self._members = int(monitor['online_members'])
         self._all = int(monitor['online_all'])
         self._all = int(monitor['online_all'])
         self._om = self._members
         self._om = self._members
         self._oa = self._all
         self._oa = self._all
-        if (monitor.expired('online_all', frequency) or
+        if (self._mode != 'no' or monitor.expired('online_all', frequency) or
                 monitor.expired('online_members', frequency)):
                 monitor.expired('online_members', frequency)):
             self.count_sessions()
             self.count_sessions()
 
 
@@ -40,41 +41,14 @@ class MembersOnline(object):
         return self._members
         return self._members
 
 
     def sync(self):
     def sync(self):
-        if self._members != self._om:
-            self.monitor['online_members'] = self._members
-        if self._all != self._oa:
-            self.monitor['online_all'] = self._all
-
-    def stats(self, request=None):
-        # Are we request-aware?
-        if not request:
-            return {
-                    'members': self.members,
-                    'all': self.all,
-                   }
-
-        online = self.stats()
-
-        # Here we check for signs that online stats are out of sync
-        try:
-            if not online['members'] and request.user.is_authenticated():
-                raise ValueError()
-            if online['members'] > online['all']:
-                raise ValueError()
-            if (online['members'] == online['all'] and
-                    not request.user.is_authenticated()):
-                raise ValueError()
-            return online
-        except ValueError:
-            if request.session.matched:
-                self.count_sessions()
-                return self.stats()
-            else:
-                if request.user.is_authenticated() and not online['members']:
-                    online['members'] += 1
-                if online['members'] > online['all']:
-                    online['all'] = online['members']
-                if request.user.is_anonymous() and online['members'] == online['all']:
-                    online['all'] += 1
-                return online
-
+        if self._mode == 'snap':
+            if self._members != self._om:
+                self.monitor['online_members'] = self._members
+            if self._all != self._oa:
+                self.monitor['online_all'] = self._all
+
+    def stats(self):
+        return {
+                'members': self.members,
+                'all': self.all,
+               }

+ 2 - 0
templates/cranefly/index.html

@@ -136,9 +136,11 @@
         <li>
         <li>
           <span class="tooltip-top" title="{% trans %}Members{% endtrans %}"><i class="icon-user"></i> {{ monitor.users|int|intcomma }}</span>
           <span class="tooltip-top" title="{% trans %}Members{% endtrans %}"><i class="icon-user"></i> {{ monitor.users|int|intcomma }}</span>
         </li>
         </li>
+        {% if settings.online_counting != 'no' %}
         <li>
         <li>
           <span class="tooltip-top" title="{% trans %}Online{% endtrans %}"><i class="icon-map-marker"></i> {{ users_online.members|int|intcomma }} <span class="muted">{{ users_online.all|int|intcomma }}</spam></span>
           <span class="tooltip-top" title="{% trans %}Online{% endtrans %}"><i class="icon-map-marker"></i> {{ users_online.members|int|intcomma }} <span class="muted">{{ users_online.all|int|intcomma }}</spam></span>
         </li>
         </li>
+        {% endif %}
       </ul>
       </ul>
     </div>
     </div>