Просмотр исходного кода

create online tracker together with user model, add maintenance task for filling blanks. fix #563

Rafał Pitoń 9 лет назад
Родитель
Сommit
3d000343c6

+ 22 - 0
misago/users/management/commands/populateonlinetracker.py

@@ -0,0 +1,22 @@
+from django.contrib.auth import get_user_model
+from django.core.management.base import BaseCommand
+from misago.users.models import Online
+
+
+class Command(BaseCommand):
+    help = 'Populates online tracker for user accounts that lack it.'
+
+    def handle(self, *args, **options):
+        User = get_user_model()
+
+        entries_created = 0
+        queryset = User.objects.filter(online_tracker__isnull=True)
+        for user in queryset.iterator():
+            Online.objects.create(
+                user=user,
+                current_ip=user.joined_from_ip,
+                last_click=user.last_login,
+            )
+            entries_created += 1
+
+        self.stdout.write('Tracker entries created: %s' % entries_created)

+ 17 - 5
misago/users/models/user.py

@@ -1,8 +1,8 @@
 from hashlib import md5
 
-from django.contrib.auth.models import (AbstractBaseUser, PermissionsMixin,
-                                        UserManager as BaseUserManager,
-                                        AnonymousUser as DjangoAnonymousUser)
+from django.contrib.auth.models import (
+    AbstractBaseUser, PermissionsMixin, UserManager as BaseUserManager,
+    AnonymousUser as DjangoAnonymousUser)
 from django.core.mail import send_mail
 from django.core.urlresolvers import reverse
 from django.db import IntegrityError, models, transaction
@@ -100,8 +100,13 @@ class UserManager(BaseUserManager):
                 extra_fields['subscribe_to_replied_threads'] = new_value
 
             now = timezone.now()
-            user = self.model(is_staff=False, is_superuser=False,
-                              last_login=now, joined_on=now, **extra_fields)
+            user = self.model(
+                is_staff=False,
+                is_superuser=False,
+                last_login=now,
+                joined_on=now,
+                **extra_fields
+            )
 
             user.set_username(username)
             user.set_email(email)
@@ -125,6 +130,13 @@ class UserManager(BaseUserManager):
 
             user.save(update_fields=['avatar_hash', 'acl_key'])
 
+            # populate online tracker with default value
+            Online.objects.create(
+                user=user,
+                current_ip=extra_fields['joined_from_ip'],
+                last_click=now,
+            )
+
             return user
 
     def create_superuser(self, username, email, password,

+ 6 - 4
misago/users/online/utils.py

@@ -28,8 +28,10 @@ def get_user_status(user, acl):
         user_status['banned_until'] = user_ban.expires_on
 
     try:
-        if not user.is_hiding_presence or acl['can_see_hidden_users']:
-            online_tracker = user.online_tracker
+        online_tracker = user.online_tracker
+        is_hidden = user.is_hiding_presence and not acl['can_see_hidden_users']
+
+        if online_tracker and not is_hidden:
             if online_tracker.last_click >= timezone.now() - ACTIVITY_CUTOFF:
                 user_status['is_online'] = True
                 user_status['last_click'] = online_tracker.last_click
@@ -64,11 +66,11 @@ def make_users_status_aware(users, acl, fetch_state=False):
     if fetch_state:
         # Fill ban cache on users
         for ban_cache in BanCache.objects.filter(user__in=users_dict.keys()):
-            user.ban_cache = ban_cache
+            users_dict[ban_cache.user_id].ban_cache = ban_cache
 
         # Fill user online trackers
         for online_tracker in Online.objects.filter(user__in=users_dict.keys()):
-            user.online_tracker = online_tracker
+            users_dict[online_tracker.user_id].online_tracker = online_tracker
 
     # Fill user states
     for user in users:

+ 24 - 0
misago/users/tests/test_populateonlinetracker.py

@@ -0,0 +1,24 @@
+from django.contrib.auth import get_user_model
+from django.test import TestCase
+from django.utils.six import StringIO
+
+from misago.users.management.commands import populateonlinetracker
+from misago.users.models import Online
+
+
+class PopulateOnlineTrackerTests(TestCase):
+    def test_populate_user_online(self):
+        """user account without online tracker gets one"""
+        User = get_user_model()
+
+        test_user = User.objects.create_user('Bob', 'bob@bob.com', 'pass123')
+
+        Online.objects.filter(user=test_user).delete()
+        self.assertEqual(Online.objects.filter(user=test_user).count(), 0)
+
+        out = StringIO()
+        populateonlinetracker.Command().execute(stdout=out)
+        command_output = out.getvalue().splitlines()[0].strip()
+
+        self.assertEqual(command_output, 'Tracker entries created: 1')
+        self.assertEqual(Online.objects.filter(user=test_user).count(), 1)

+ 4 - 1
misago/users/tests/test_user_create_api.py

@@ -4,6 +4,7 @@ from django.core.urlresolvers import reverse
 
 from misago.conf import settings
 
+from misago.users.models import Online
 from misago.users.testutils import UserTestCase
 
 
@@ -46,7 +47,9 @@ class UserCreateTests(UserTestCase):
 
         User = get_user_model()
         User.objects.get_by_username('Bob')
-        User.objects.get_by_email('bob@bob.com')
+
+        test_user = User.objects.get_by_email('bob@bob.com')
+        self.assertEqual(Online.objects.filter(user=test_user).count(), 1)
 
         response = self.client.get(reverse('misago:index'))
         self.assertIn('Bob', response.content)