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

Moved other user model fields from 0.5 to 0.6

Rafał Pitoń 11 лет назад
Родитель
Сommit
88d8a24048

+ 1 - 0
misago/conf/defaults.py

@@ -107,6 +107,7 @@ INSTALLED_APPS = (
 )
 
 MIDDLEWARE_CLASSES = (
+    'misago.users.middleware.RealIPMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',

+ 1 - 0
misago/urls.py

@@ -15,6 +15,7 @@ urlpatterns += patterns('',
     url(r'^', include('misago.users.urls')),
 )
 
+
 # Register Misago ACP
 if settings.MISAGO_ADMIN_PATH:
     # Admin patterns recognised by Misago

+ 13 - 1
misago/users/middleware.py

@@ -2,6 +2,15 @@ from django.utils import timezone
 from misago.users.models import AnonymousUser, Online
 
 
+class RealIPMiddleware(object):
+    def process_request(self, request):
+        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
+        if x_forwarded_for:
+            request._misago_real_ip = x_forwarded_for.split(',')[0]
+        else:
+            request._misago_real_ip = request.META.get('REMOTE_ADDR')
+
+
 class UserMiddleware(object):
     def process_request(self, request):
         if request.user.is_anonymous():
@@ -14,7 +23,8 @@ class OnlineTrackerMiddleware(object):
             try:
                 request._misago_online_tracker = request.user.online_tracker
             except Online.DoesNotExist:
-                online_tracker = Online.objects.create(user=request.user)
+                online_tracker = Online.objects.create(
+                    user=request.user, current_ip=request._misago_real_ip)
                 request.user.online_tracker = online_tracker
                 request._misago_online_tracker = online_tracker
         else:
@@ -29,9 +39,11 @@ class OnlineTrackerMiddleware(object):
                     # User logged off, update his last visit and blam tracker
                     user = tracker.user
                     user.last_active = tracker.last_click
+                    user.last_ip = tracker.current_ip
                     user.save(update_fields=['last_active'])
                 else:
                     # Bump user's tracker time
+                    tracker.current_ip = request._misago_real_ip
                     tracker.last_click = timezone.now()
                     tracker.save(update_fields=['last_click'])
 

+ 36 - 4
misago/users/migrations/0001_initial.py

@@ -28,15 +28,46 @@ class Migration(migrations.Migration):
                 ('email', models.EmailField(max_length=255, db_index=True)),
                 ('email_hash', models.CharField(unique=True, max_length=32)),
                 ('joined_on', models.DateTimeField(default=django.utils.timezone.now, verbose_name='joined on')),
+                ('joined_from_ip', models.GenericIPAddressField()),
                 ('last_active', models.DateTimeField(null=True, blank=True)),
+                ('last_ip', models.GenericIPAddressField(null=True, blank=True)),
+                ('presence_visibility', models.PositiveIntegerField(default=0)),
+                ('timezone', models.CharField(max_length=255, default='utc')),
                 ('title', models.CharField(max_length=255, null=True, blank=True)),
-                ('activation_requirement', models.PositiveIntegerField(default=0)),
+                ('requires_activation', models.PositiveIntegerField(default=0)),
                 ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into admin sites.', verbose_name='staff status')),
                 ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
                 ('acl_key', models.CharField(max_length=12, null=True, blank=True)),
                 ('groups', models.ManyToManyField(to='auth.Group', verbose_name='groups', blank=True)),
                 ('roles', models.ManyToManyField(to='misago_acl.Role')),
                 ('user_permissions', models.ManyToManyField(to='auth.Permission', verbose_name='user permissions', blank=True)),
+                ('is_avatar_banned', models.BooleanField(default=False)),
+                ('avatar_type', models.CharField(max_length=10, null=True, blank=True)),
+                ('avatar_image', models.CharField(max_length=255, null=True, blank=True)),
+                ('avatar_original', models.CharField(max_length=255, null=True, blank=True)),
+                ('avatar_temp', models.CharField(max_length=255, null=True, blank=True)),
+                ('avatar_crop', models.CharField(max_length=255, null=True, blank=True)),
+                ('avatar_ban_user_message', models.TextField(null=True, blank=True)),
+                ('avatar_ban_staff_message', models.TextField(null=True, blank=True)),
+                ('is_signature_banned', models.BooleanField(default=False)),
+                ('signature', models.TextField(null=True, blank=True)),
+                ('signature_preparsed', models.TextField(null=True, blank=True)),
+                ('signature_ban_user_message', models.TextField(null=True, blank=True)),
+                ('signature_ban_staff_message', models.TextField(null=True, blank=True)),
+                ('warning_level', models.PositiveIntegerField(default=0)),
+                ('warning_level_update_on', models.DateTimeField(null=True, blank=True)),
+                ('following', models.PositiveIntegerField(default=0)),
+                ('followers', models.PositiveIntegerField(default=0)),
+                ('new_alerts', models.PositiveIntegerField(default=0)),
+                ('limit_private_thread_invites', models.PositiveIntegerField(default=0)),
+                ('unread_private_threads', models.PositiveIntegerField(default=0)),
+                ('sync_unred_private_threads', models.BooleanField(default=False)),
+                ('subscribe_to_started_threads', models.PositiveIntegerField(default=0)),
+                ('subscribe_to_replied_threads', models.PositiveIntegerField(default=0)),
+                ('threads', models.PositiveIntegerField(default=0)),
+                ('posts', models.PositiveIntegerField(default=0)),
+                ('last_post', models.DateTimeField(null=True, blank=True)),
+                ('last_search', models.DateTimeField(null=True, blank=True)),
             ],
             options={
                 'abstract': False,
@@ -49,13 +80,14 @@ class Migration(migrations.Migration):
             condition='is_staff = TRUE',
         ),
         CreatePartialIndex(
-            field='User.activation_requirement',
-            index_name='misago_users_user_activation_requirement_partial',
-            condition='activation_requirement > 0',
+            field='User.requires_activation',
+            index_name='misago_users_user_requires_activation_partial',
+            condition='requires_activation > 0',
         ),
         migrations.CreateModel(
             name='Online',
             fields=[
+                ('current_ip', models.GenericIPAddressField()),
                 ('last_click', models.DateTimeField(default=django.utils.timezone.now)),
                 ('user', models.OneToOneField(primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)),
             ],

+ 2 - 2
misago/users/migrations/0002_users_settings.py

@@ -125,7 +125,7 @@ def create_users_settings_group(apps, schema_editor):
                     'field_extra': {
                         'choices': (
                             ('no', _("Don't watch")),
-                            ('', _("Put on watched threads list")),
+                            ('watch', _("Put on watched threads list")),
                             ('watch_email', _("Put on watched threads "
                                               "list and e-mail user when "
                                               "somebody replies")),
@@ -140,7 +140,7 @@ def create_users_settings_group(apps, schema_editor):
                     'field_extra': {
                         'choices': (
                             ('no', _("Don't watch")),
-                            ('', _("Put on watched threads list")),
+                            ('watch', _("Put on watched threads list")),
                             ('watch_email', _("Put on watched threads "
                                               "list and e-mail user when "
                                               "somebody replies")),

+ 98 - 2
misago/users/models/user.py

@@ -9,6 +9,7 @@ from django.utils.translation import ugettext_lazy as _
 
 from misago.acl import get_user_acl
 from misago.acl.models import Role
+from misago.conf import settings
 from misago.core.utils import slugify
 
 from misago.users.models.rank import Rank
@@ -22,6 +23,34 @@ __all__ = [
 ]
 
 
+ACTIVATION_REQUIRED_NONE = 0
+ACTIVATION_REQUIRED_EMAIL = 1
+ACTIVATION_REQUIRED_ADMIN = 2
+
+
+PRESENCE_VISIBILITY_ALL = 0
+PRESENCE_VISIBILITY_FOLLOWED = 1
+PRESENCE_VISIBILITY_ALLOWED = 2
+
+PRESENCE_VISIBILITY_CHOICES = (
+    (PRESENCE_VISIBILITY_ALL, _("Everyone")),
+    (PRESENCE_VISIBILITY_FOLLOWED, _("Users I follow")),
+    (PRESENCE_VISIBILITY_ALLOWED, _("Users with permission"))
+)
+
+
+AUTO_SUBSCRIBE_NONE = 0
+AUTO_SUBSCRIBE_WATCH = 1
+AUTO_SUBSCRIBE_WATCH_AND_EMAIL = 2
+
+AUTO_SUBSCRIBE_CHOICES = (
+    (AUTO_SUBSCRIBE_NONE, _("Do nothing.")),
+    (AUTO_SUBSCRIBE_WATCH, _("Add to watched list.")),
+    (AUTO_SUBSCRIBE_WATCH_AND_EMAIL,
+     _("Add to watched list with e-mail notification."))
+)
+
+
 class UserManager(BaseUserManager):
     def create_user(self, username, email, password=None, **extra_fields):
         with transaction.atomic():
@@ -34,6 +63,26 @@ class UserManager(BaseUserManager):
             validate_email(email)
             validate_password(password)
 
+            if not 'joined_from_ip' in extra_fields:
+                extra_fields['joined_from_ip'] = '127.0.0.1'
+
+            if not 'timezone' in extra_fields:
+                extra_fields['timezone'] = settings.default_timezone
+
+            WATCH_DICT = {
+                'no': AUTO_SUBSCRIBE_NONE,
+                'watch': AUTO_SUBSCRIBE_WATCH,
+                'watch_email': AUTO_SUBSCRIBE_WATCH_AND_EMAIL,
+            }
+
+            if not 'subscribe_to_started_threads' in extra_fields:
+                new_value = WATCH_DICT[settings.subscribe_start]
+                extra_fields['subscribe_to_started_threads'] = new_value
+
+            if not 'subscribe_to_replied_threads' in extra_fields:
+                new_value = WATCH_DICT[settings.subscribe_reply]
+                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)
@@ -102,18 +151,64 @@ class User(AbstractBaseUser, PermissionsMixin):
     email = models.EmailField(max_length=255, db_index=True)
     email_hash = models.CharField(max_length=32, unique=True)
     joined_on = models.DateTimeField(_('joined on'), default=timezone.now)
+    joined_from_ip = models.GenericIPAddressField()
     last_active = models.DateTimeField(null=True, blank=True)
+    last_ip = models.GenericIPAddressField(null=True, blank=True)
+    presence_visibility = models.PositiveIntegerField(
+        default=PRESENCE_VISIBILITY_ALL)
+
+    timezone = models.CharField(max_length=255, default='utc')
+
     rank = models.ForeignKey(
         'Rank', null=True, blank=True, on_delete=models.PROTECT)
     title = models.CharField(max_length=255, null=True, blank=True)
-    activation_requirement = models.PositiveIntegerField(default=0)
+    requires_activation = models.PositiveIntegerField(
+        default=ACTIVATION_REQUIRED_NONE)
     is_staff = models.BooleanField(
         _('staff status'), default=False,
         help_text=_('Designates whether the user can log into admin sites.'))
     roles = models.ManyToManyField('misago_acl.Role')
     acl_key = models.CharField(max_length=12, null=True, blank=True)
 
-    is_active = True
+    is_avatar_banned = models.BooleanField(default=False)
+    avatar_type = models.CharField(max_length=10, null=True, blank=True)
+    avatar_image = models.CharField(max_length=255, null=True, blank=True)
+    avatar_original = models.CharField(max_length=255, null=True, blank=True)
+    avatar_temp = models.CharField(max_length=255, null=True, blank=True)
+    avatar_crop = models.CharField(max_length=255, null=True, blank=True)
+    avatar_ban_user_message = models.TextField(null=True, blank=True)
+    avatar_ban_staff_message = models.TextField(null=True, blank=True)
+
+    is_signature_banned = models.BooleanField(default=False)
+    signature = models.TextField(null=True, blank=True)
+    signature_preparsed = models.TextField(null=True, blank=True)
+    signature_ban_user_message = models.TextField(null=True, blank=True)
+    signature_ban_staff_message = models.TextField(null=True, blank=True)
+
+    warning_level = models.PositiveIntegerField(default=0)
+    warning_level_update_on = models.DateTimeField(null=True, blank=True)
+
+    following = models.PositiveIntegerField(default=0)
+    followers = models.PositiveIntegerField(default=0)
+
+    new_alerts = models.PositiveIntegerField(default=0)
+
+    limit_private_thread_invites = models.PositiveIntegerField(default=0)
+    unread_private_threads = models.PositiveIntegerField(default=0)
+    sync_unred_private_threads = models.BooleanField(default=False)
+
+    subscribe_to_started_threads = models.PositiveIntegerField(
+        default=AUTO_SUBSCRIBE_NONE)
+    subscribe_to_replied_threads = models.PositiveIntegerField(
+        default=AUTO_SUBSCRIBE_NONE)
+
+    threads = models.PositiveIntegerField(default=0)
+    posts = models.PositiveIntegerField(default=0)
+
+    last_post = models.DateTimeField(null=True, blank=True)
+    last_search = models.DateTimeField(null=True, blank=True)
+
+    is_active = True # Django's is_active means "is not deleted"
 
     USERNAME_FIELD = 'username_slug'
     REQUIRED_FIELDS = ['email']
@@ -197,6 +292,7 @@ class User(AbstractBaseUser, PermissionsMixin):
 class Online(models.Model):
     user = models.OneToOneField(User, primary_key=True,
                                 related_name='online_tracker')
+    current_ip = models.GenericIPAddressField()
     last_click = models.DateTimeField(default=timezone.now)
 
 

+ 2 - 1
misago/users/views/admin/users.py

@@ -55,7 +55,8 @@ class NewUser(UserAdmin, generic.ModelFormView):
             form.cleaned_data['email'],
             form.cleaned_data['new_password'],
             title=form.cleaned_data['title'],
-            rank=form.cleaned_data.get('rank'))
+            rank=form.cleaned_data.get('rank'),
+            joined_from_ip=request._misago_real_ip)
 
         if form.cleaned_data.get('staff_level'):
             new_user.staff_level = form.cleaned_data['staff_level']